Куратор раздела

Партиции
Партиционирование таблиц (оно же секционирование) - это метод проектирования базы данных, используемый для разделения большой таблицы на более мелкие, более управляемые фрагменты, называемые разделами. Каждый раздел по сути является отдельной таблицей, которая хранит подмножество исходных данных. Этот метод может значительно улучшить производительность запросов и управление данными для больших наборов данных.
Разделение может быть выполнено на основе одного или нескольких столбцов, таких как столбец даты или диапазон значений. Например, вы можете разбить таблицу на основе даты записей, где каждый раздел представляет данные для определенного диапазона дат. При запросе данных СУБД может быстро исключить разделы, которые не имеют отношения к запросу, что приводит к более быстрому выполнению запроса.
Каждый раздел — это отдельный сегмент таблицы, которым можно управлять независимо. Например, вы можете разделить данные о продажах по годам, при этом каждый год будет находиться в своем собственном разделе.

Большинство СУБД позволяет дробить партиции еще на секции - субпартиции.
Преимущества партицированных таблиц:
-
Улучшенная производительность запросов: разделение позволяет базе данных быстро сузить данные до определенного раздела, уменьшая объем данных, которые необходимо сканировать во время запросов. Это приводит к более быстрому времени выполнения запросов, особенно для больших наборов данных.
-
Более простое управление данными: с помощью секционирования таблиц вы можете легко управлять большими наборами данных, разделяя их на более мелкие, более управляемые секции. Это может упростить такие задачи, как архивирование данных, очистка данных, а также операции резервного копирования и восстановления.
-
Улучшенная загрузка и индексация данных: при загрузке данных в секционированную таблицу процесс может быть распараллелен, что приводит к более быстрому приему данных. Кроме того, индексы в секционированных таблицах могут быть более эффективными, поскольку им нужно охватывать только меньший подмножество данных.
-
Экономичное хранение: разделение позволяет хранить старые или редко используемые данные на более дешевых носителях, а часто используемые данные — на более быстрых устройствах хранения.
Существует два основных варианта партиционирования в СУБД — горизонтальное и вертикальное.
Горизонтальное партиционирование предполагает разделение таблицы на партиции, основанное на строках. Каждая партиция содержит определенное количество строк. Такой подход используется, когда таблица имеет очень большой объем данных и необходима более эффективная обработка.
Вертикальное партиционирование, в свою очередь, разделяет таблицу на партиции, основываясь на столбцах. Каждая партиция содержит определенный набор столбцов. Такой подход может быть полезным, когда таблица имеет много столбцов и только некоторые из них часто используются.
Комбинация горизонтального и вертикального - Редкое сочетание горизонтального и вертикального разбиения, которое делит таблицу как по строкам, так и по столбцам.
В целом, принцип партиционирования во всех СУБД одинаковый, но как всегда есть нюансы. Для конкретики, разберем устройство партиционивания в PostgreSQL.
PostgreSQL предлагает различные методы секционирования, в том числе:
-
Разделение диапазона
-
Разделение списка
-
Разделение хэша
Разделение диапазона (Range Partitioning)
Принцип работы: Таблица разделяется на партиции по диапазонам значений ключевого столбца. Каждая партиция содержит данные, попадающие в определенный диапазон.
Когда использовать:
- Для временных данных (по датам, месяцам, годам)
- Для числовых значений с естественными диапазонами (например, суммы, возраст)
Пример:
-- Создаем основную партиционированную таблицу
CREATE TABLE sales (
id SERIAL,
sale_date DATE NOT NULL,
product_id INT,
amount DECIMAL(10, 2)
) PARTITION BY RANGE (sale_date);
-- Создаем партиции для каждого квартала 2023 года
CREATE TABLE sales_q1_2023 PARTITION OF sales
FOR VALUES FROM ('2023-01-01') TO ('2023-04-01');
CREATE TABLE sales_q2_2023 PARTITION OF sales
FOR VALUES FROM ('2023-04-01') TO ('2023-07-01');
CREATE TABLE sales_q3_2023 PARTITION OF sales
FOR VALUES FROM ('2023-07-01') TO ('2023-10-01');
CREATE TABLE sales_q4_2023 PARTITION OF sales
FOR VALUES FROM ('2023-10-01') TO ('2024-01-01');
-- Создаем дефолтную партицию для данных вне указанных диапазонов
CREATE TABLE sales_default PARTITION OF sales DEFAULT;Особенности:
- Диапазоны не должны пересекаться
- Можно создавать партиции заранее для будущих данных
- Эффективно для запросов с условиями по ключу партиционирования
Разделение списка (List Partitioning)
Принцип работы: Таблица разделяется на партиции по списку значений ключевого столбца. Каждая партиция содержит данные с определенными значениями.
Когда использовать:
- Когда данные естественным образом группируются по дискретным значениям
- Для географических регионов, категорий продуктов и т.д.
Пример:
-- Создаем основную партиционированную таблицу
CREATE TABLE employees (
id SERIAL,
name TEXT,
department TEXT,
salary DECIMAL(10, 2)
) PARTITION BY LIST (department);
-- Создаем партиции для каждого отдела
CREATE TABLE employees_hr PARTITION OF employees
FOR VALUES IN ('HR', 'Human Resources');
CREATE TABLE employees_it PARTITION OF employees
FOR VALUES IN ('IT', 'Information Technology');
CREATE TABLE employees_sales PARTITION OF employees
FOR VALUES IN ('Sales', 'Marketing');
CREATE TABLE employees_finance PARTITION OF employees
FOR VALUES IN ('Finance', 'Accounting');
-- Партиция для всех остальных отделов
CREATE TABLE employees_default PARTITION OF employees DEFAULT;Особенности:
- Значения в списке не должны пересекаться между партициями
- Хорошо подходит для данных с известным набором категорий
- Эффективно для запросов с фильтрацией по категориям
Разделение хэша (Hash Partitioning)
Принцип работы: Таблица разделяется на партиции с использованием хэш-функции от значения ключевого столбца. Данные распределяются по партициям равномерно.
Когда использовать:
- Когда нет естественного критерия для диапазонного или спискового разделения
- Для равномерного распределения данных и нагрузки
- Для больших таблиц, где важна параллельная обработка
Пример:
-- Создаем основную партиционированную таблицу
CREATE TABLE user_sessions (
session_id UUID,
user_id BIGINT,
created_at TIMESTAMP,
session_data JSONB
) PARTITION BY HASH (user_id);
-- Создаем 4 партиции, используя остаток от деления хэша
CREATE TABLE user_sessions_p0 PARTITION OF user_sessions
FOR VALUES WITH (MODULUS 4, REMAINDER 0);
CREATE TABLE user_sessions_p1 PARTITION OF user_sessions
FOR VALUES WITH (MODULUS 4, REMAINDER 1);
CREATE TABLE user_sessions_p2 PARTITION OF user_sessions
FOR VALUES WITH (MODULUS 4, REMAINDER 2);
CREATE TABLE user_sessions_p3 PARTITION OF user_sessions
FOR VALUES WITH (MODULUS 4, REMAINDER 3);
Особенности:
-
Обеспечивает равномерное распределение данных
-
Количество партиций лучше выбирать степенью двойки
-
Не поддерживает исключение партиций при запросах (partition pruning) так же эффективно, как range/list
-
Хорошо подходит для распределения нагрузки при параллельных операциях
PostgreSQL также поддерживает:
-
Композитное партиционирование (сочетание разных методов)
-
Присоединение внешних таблиц как партиций (с PostgreSQL 12)
-
Автоматическое создание партиций (с помощью расширений)
Подробнее можно почитать здесь: