Partycjnowanie tablicy w PostgreSQL

W poniższym przykładzie pokazuję, jak zdefiniować funkcję wyzwalaną, która automatycznie tworzy nowe partycje w tabeli na podstawie daty. Taka funkcja przydaje się zwłaszcza przy pracy z dużymi zbiorami danych, gdzie miesięczne partycjonowanie pozwala na łatwiejsze zarządzanie danymi i poprawę wydajności.

Poniższy kod tworzy funkcję, która będzie wywoływana przy dodawaniu nowego rekordu do głównej tabeli. Jeśli partycja dla bieżącego miesiąca nie istnieje, funkcja ją utworzy i doda do odpowiedniego schematu. Dzięki temu nie musimy ręcznie dodawać nowych tabel co miesiąc – system sam tworzy je w trakcie pracy.

CREATE OR REPLACE FUNCTION log_insert_trigger()
RETURNS TRIGGER AS $$
DECLARE l_year double precision;
DECLARE l_month double precision;
DECLARE l_year_next double precision;
DECLARE l_month_next double precision;
DECLARE s_month text;
DECLARE s_table text;
DECLARE i_tbl_count int;
BEGIN
    l_year:=(EXTRACT(YEAR FROM NEW."downloadDate"));  
    l_month:=(EXTRACT(MONTH FROM NEW."downloadDate"));
 
    l_year_next:=(EXTRACT(YEAR FROM (NEW."downloadDate" + interval '1 month')));  
    l_month_next:=(EXTRACT(MONTH FROM (NEW."downloadDate" + interval '1 month')));
 
    IF (l_month < 10) THEN
        s_month := '0' || l_month; 
    ELSE
        s_month := l_month;
    END IF;
     
    s_table := 'log_y' || l_year || 'm' || s_month;
     
    SELECT count(*) INTO i_tbl_count FROM pg_tables WHERE tablename = s_table AND schemaname = 'lps';
    IF (i_tbl_count < 1) THEN
        EXECUTE 'CREATE TABLE lps.' || s_table || ' ('
            || 'CHECK ( "downloadDate" >= DATE ''' || l_year || '-' || l_month || '-01'' '
            || 'AND "downloadDate" < DATE ''' || l_year_next || '-' || l_month_next || '-01'' )'
            || ') INHERITS (lps.log);';
           
    END IF;
            
    EXECUTE 'INSERT INTO lps.' || s_table || ' VALUES ($1.*)' USING NEW;    
    RETURN NULL;
END;
$$
LANGUAGE plpgsql;

Dzięki takiemu podejściu funkcja jest w pełni automatyczna i nie wymaga przygotowywania partycji z wyprzedzeniem.