---
title: "Ruby on Rails a klucze główne w partycjonowaniu PostgreSQL 14"
url: https://michalasobczak.pl/pl/posts/ruby-on-rails-vs-postgresql-14-partitioning-primary-keys.html
author: "Michał Sobczak"
description: "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."
published: 2022-09-08T11:49:21.000Z
updated: 2022-09-08T11:49:23.000Z
language: pl
categories: ["Technology"]
tags: ["PostgreSQL", "Ruby / Rails"]
license: CC BY-NC-ND 4.0 (https://creativecommons.org/licenses/by-nc-nd/4.0/)
---
# Ruby on Rails a klucze główne w partycjonowaniu PostgreSQL 14

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ą:

```sql
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ę:

```sql
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:

```text
self.primary_key = :id
```

Działa bez zarzutu.
