Gymterview
middle

Что такое партиционирование (partitioning) таблиц?

Партиционирование — это разбиение большой таблицы на несколько физических частей (партиций), при этом логически они остаются единой таблицей. Повышает производительность запросов (partition pruning) и упрощает обслуживание. С PostgreSQL 10 поддерживается декларативное партиционирование.

RANGE-партиционирование (по диапазону)

Пример
CREATE TABLE transactions (
    id bigserial,
    account_id bigint NOT NULL,
    amount numeric(15, 2) NOT NULL,
    created_at timestamptz NOT NULL,
    PRIMARY KEY (id, created_at)
) PARTITION BY RANGE (created_at);

CREATE TABLE transactions_2024_01 PARTITION OF transactions
    FOR VALUES FROM ('2024-01-01') TO ('2024-02-01');
CREATE TABLE transactions_2024_02 PARTITION OF transactions
    FOR VALUES FROM ('2024-02-01') TO ('2024-03-01');
CREATE TABLE transactions_default PARTITION OF transactions DEFAULT;

LIST-партиционирование (по списку значений)

Пример
CREATE TABLE accounts (
    id bigserial,
    client_id bigint,
    currency char(3) NOT NULL,
    balance numeric(15, 2),
    PRIMARY KEY (id, currency)
) PARTITION BY LIST (currency);

CREATE TABLE accounts_rub PARTITION OF accounts FOR VALUES IN ('RUB');
CREATE TABLE accounts_usd PARTITION OF accounts FOR VALUES IN ('USD');
CREATE TABLE accounts_eur PARTITION OF accounts FOR VALUES IN ('EUR');
CREATE TABLE accounts_other PARTITION OF accounts DEFAULT;

HASH-партиционирование (по хешу)

Пример
CREATE TABLE session_data (
    session_id uuid NOT NULL,
    data jsonb,
    PRIMARY KEY (session_id)
) PARTITION BY HASH (session_id);

CREATE TABLE session_data_0 PARTITION OF session_data
    FOR VALUES WITH (MODULUS 4, REMAINDER 0);
-- ... и так далее для REMAINDER 1, 2, 3

Преимущества

  • Partition pruning — PostgreSQL сканирует только нужные партиции
  • Быстрое удаление старых данных: DROP TABLE transactions_2023_01 вместо DELETE
  • Индексы меньше — быстрее обслуживаются
  • VACUUM работает на отдельных партициях

Рекомендации

  • Партиционирование имеет смысл для таблиц от нескольких миллионов строк
  • Ключ партиционирования должен входить в PRIMARY KEY
  • Индексы создаются на каждой партиции отдельно (или автоматически при создании на родительской таблице)

На собеседовании: три типа (RANGE, LIST, HASH) — назовите с примером. RANGE для временных рядов (логи, транзакции), LIST для дискретных значений (валюта, регион), HASH для равномерного распределения. Упомяните partition pruning и быстрое удаление партиций через DROP вместо DELETE.