Ruby on Rails a klucze główne w partycjonowaniu PostgreSQL 14
Przetłumaczone automatycznie z angielskiego. Przeczytaj oryginał
Od PostgreSQL 10 mamy do dyspozycji nowy rodzaj partycjonowania – deklaratywne. Wcześniej było dziedziczenie, które też jest dobre, ale ma pewne ograniczenia. Teraz, przy partycjonowaniu deklaratywnym, użytkownik nie musi podawać nazwy partycji podczas wstawiania danych. Aby utworzyć tabelę partycjonowaną:
CREATE TABLE tablename
(
id BIGSERIAL NOT NULL,
created_at TIMESTAMP WITHOUT TIME ZONE NOT NULL,
CONSTRAINT tablename_pkey PRIMARY KEY (id, created_at)
) PARTITION BY RANGE(created_at);Kilka rzeczy wymaga wyjaśnienia. Pierwsza to typ danych BIGSERIAL. To większa odmiana typu całkowitoliczbowego z automatycznym tworzeniem sekwencji, co jest bardzo wygodne. Druga to PARTITION BY RANGE(columnname). Określa ona, że dane będą rozkładane między partycje na podstawie zakresu dat created_at. Pozytywnie wpływa to na wydajność zapytań.
Aby utworzyć partycję:
CREATE TABLE tabelename_2022_09 PARTITION OF tablename
FOR VALUES FROM ('2022-09-01 00:00:00.00') TO ('2022-09-30 23:59:59.99');Przy dziedziczeniu tabel stosowałem partycjonowanie z ponad 1000 tabel. Ogólnie rzecz biorąc, PostgreSQL, nawet w starszych wersjach, bez problemu radził sobie ze 100 000 tabel na jednym serwerze i wolumenem danych około 10 TB. Jednak przy partycjonowaniu deklaratywnym trzeba pamiętać, że przy wykonywaniu zapytania na tabeli głównej na każdej partycji zakładana jest blokada współdzielona, a to kosztuje pamięć. Choć może to być pewne uproszczenie, trzeba zwiększyć parametr max_locks_per_transaction tak, aby zmieścił wymaganą liczbę utworzonych i podpiętych partycji. Jeśli nie potrzebujesz dostępu online do jakichś starych danych albo utworzyłeś z wyprzedzeniem przyszłe partycje, to albo ich nie podpinaj, albo po prostu odepnij, jeśli są nieużywane.
Ostatnia i najważniejsza rzecz dotyczy wielokolumnowego klucza głównego. Ruby on Rails i biblioteka ActiveRecord domyślnie go nie obsługują. Można użyć jakiegoś gema, żeby obejść to ograniczenie, ale wystarczy jedynie wskazać konkretną kolumnę w definicji modelu:
self.primary_key = :idDziała bez zarzutu.