Перейти к основному содержимому

Секционирование по выражениям (рекомендуется)

Начиная с версии 1.5.0, Selena поддерживает секционирование по выражениям (ранее известное как автоматическое секционирование), которое является более гибким и удобным для пользователя. Этот метод секционирования подходит для большинства сценариев, таких как запросы и управление данными на основе непрерывных временных диапазонов или значений ENUM.

Вам нужно только указать простое выражение секционирования (либо выражение временной функции, либо выражение столбца) при создании таблицы. Во время загрузки данных Selena автоматически создаст секции на основе данных и правила, определенного в выражении секционирования. Вам больше не нужно вручную создавать множество секций при создании таблицы или настраивать свойства динамического секционирования.

Секционирование на основе выражения временной функции

Если вы часто запрашиваете и управляете данными на основе непрерывных временных диапазонов, вам нужно только указать столбец типа даты (DATE или DATETIME) в качестве столбца секционирования и указать год, месяц, день или час в качестве гранулярности секционирования в выражении временной функции. Selena автоматически создаст секции и установит даты начала и окончания секций или datetime на основе загруженных данных и выражения секционирования.

Однако в некоторых особых сценариях, таких как секционирование исторических данных по месяцам и недавних данных по дням, вы должны использовать range partitioning для создания секций.

Синтаксис

PARTITION BY expression
...
[ PROPERTIES( 'partition_live_number' = 'xxx' ) ]

expression ::=
{ date_trunc ( <time_unit> , <partition_column> ) |
time_slice ( <partition_column> , INTERVAL <N> <time_unit> [ , boundary ] ) }

Параметры

expression

Обязательный: ДА
Описание: В настоящее время поддерживаются только функции date_trunc и time_slice. Если вы используете функцию time_slice, вам не нужно передавать параметр boundary. Это связано с тем, что в этом сценарии значением по умолчанию и допустимым значением для этого параметра является floor, и значение не может быть ceil.

time_unit

Обязательный: ДА
Описание: Гранулярность секционирования, которая может быть hour, day, month или year. Гранулярность секционирования week не поддерживается. Если гранулярность секционирования hour, столбец секционирования должен быть типа данных DATETIME и не может быть типа данных DATE.

partition_column

Обязательный: ДА
Описание: Имя столбца секционирования.

  • Столбец секционирования может быть только типа данных DATE или DATETIME. Столбец секционирования допускает значения NULL.
  • Столбец секционирования может быть типа данных DATE или DATETIME, если используется функция date_trunc. Столбец секционирования должен быть типа данных DATETIME, если используется функция time_slice.
  • Если столбец секционирования типа данных DATE, поддерживаемый диапазон [0000-01-01 ~ 9999-12-31]. Если столбец секционирования типа данных DATETIME, поддерживаемый диапазон [0000-01-01 01:01:01 ~ 9999-12-31 23:59:59].
  • В настоящее время вы можете указать только один столбец секционирования; несколько столбцов секционирования не поддерживаются.

partition_live_number

Обязательный: НЕТ
Описание: Количество самых последних секций, которые нужно сохранить. Секции сортируются в хронологическом порядке, с текущей датой в качестве эталона; секции старше текущей даты минус partition_live_number удаляются. Selena планирует задачи для управления количеством секций, и интервал планирования можно настроить через динамический параметр FE dynamic_partition_check_interval_seconds, который по умолчанию составляет 600 секунд (10 минут). Предположим, что текущая дата 4 апреля 2023 года, partition_live_number установлено в 2, а секции включают p20230401, p20230402, p20230403, p20230404. Секции p20230403 и p20230404 сохраняются, а другие секции удаляются. Если загружаются грязные данные, такие как данные из будущих дат 5 и 6 апреля, секции включают p20230401, p20230402, p20230403, p20230404, p20230405 и p20230406. Тогда секции p20230403, p20230404, p20230405 и p20230406 сохраняются, а другие секции удаляются.

Примечания по использованию

  • Во время загрузки данных Selena автоматически создает некоторые секции на основе загруженных данных, но если задание загрузки по какой-то причине завершается неудачно, секции, которые автоматически создаются Selena, не могут быть автоматически удалены.
  • Selena устанавливает максимальное количество автоматически создаваемых секций по умолчанию в 4096, что можно настроить параметром FE max_automatic_partition_number. Этот параметр может предотвратить случайное создание слишком большого количества секций.
  • Правило именования секций соответствует правилу именования для динамического секционирования.

Примеры

Пример 1: Предположим, вы часто запрашиваете данные по дням. Вы можете использовать выражение секционирования date_trunc() и установить столбец секционирования как event_day, а гранулярность секционирования как day при создании таблицы. Данные автоматически секционируются на основе дат во время загрузки. Данные одного дня хранятся в одной секции, и обрезка секций может использоваться для значительного повышения эффективности запросов.

CREATE TABLE site_access1 (
event_day DATETIME NOT NULL,
site_id INT DEFAULT '10',
city_code VARCHAR(100),
user_name VARCHAR(32) DEFAULT '',
pv BIGINT DEFAULT '0'
)
DUPLICATE KEY(event_day, site_id, city_code, user_name)
PARTITION BY date_trunc('day', event_day)
DISTRIBUTED BY HASH(event_day, site_id);

Например, когда загружаются следующие две строки данных, Selena автоматически создаст две секции, p20230226 и p20230227, с диапазонами [2023-02-26 00:00:00, 2023-02-27 00:00:00) и [2023-02-27 00:00:00, 2023-02-28 00:00:00) соответственно. Если последующие загруженные данные попадают в эти диапазоны, они автоматически направляются в соответствующие секции.

-- insert two data rows
INSERT INTO site_access1
VALUES ("2023-02-26 20:12:04",002,"New York","Sam Smith",1),
("2023-02-27 21:06:54",001,"Los Angeles","Taylor Swift",1);

-- view partitions
mysql > SHOW PARTITIONS FROM site_access1;
+-------------+---------------+----------------+---------------------+--------------------+--------+--------------+------------------------------------------------------------------------------------------------------+--------------------+---------+----------------+---------------+---------------------+--------------------------+----------+------------+----------+
| PartitionId | PartitionName | VisibleVersion | VisibleVersionTime | VisibleVersionHash | State | PartitionKey | Range | DistributionKey | Buckets | ReplicationNum | StorageMedium | CooldownTime | LastConsistencyCheckTime | DataSize | IsInMemory | RowCount |
+-------------+---------------+----------------+---------------------+--------------------+--------+--------------+------------------------------------------------------------------------------------------------------+--------------------+---------+----------------+---------------+---------------------+--------------------------+----------+------------+----------+
| 17138 | p20230226 | 2 | 2023-07-19 17:53:59 | 0 | NORMAL | event_day | [types: [DATETIME]; keys: [2023-02-26 00:00:00]; ..types: [DATETIME]; keys: [2023-02-27 00:00:00]; ) | event_day, site_id | 6 | 3 | HDD | 9999-12-31 23:59:59 | NULL | 0B | false | 0 |
| 17113 | p20230227 | 2 | 2023-07-19 17:53:59 | 0 | NORMAL | event_day | [types: [DATETIME]; keys: [2023-02-27 00:00:00]; ..types: [DATETIME]; keys: [2023-02-28 00:00:00]; ) | event_day, site_id | 6 | 3 | HDD | 9999-12-31 23:59:59 | NULL | 0B | false | 0 |
+-------------+---------------+----------------+---------------------+--------------------+--------+--------------+------------------------------------------------------------------------------------------------------+--------------------+---------+----------------+---------------+---------------------+--------------------------+----------+------------+----------+
2 rows in set (0.00 sec)

Пример 2: Если вы хотите реализовать управление жизненным циклом секций, то есть сохранить только определенное количество последних секций и удалить исторические секции, вы можете использовать свойство partition_live_number для указания количества секций для сохранения.

CREATE TABLE site_access2 (
event_day DATETIME NOT NULL,
site_id INT DEFAULT '10',
city_code VARCHAR(100),
user_name VARCHAR(32) DEFAULT '',
pv BIGINT DEFAULT '0'
)
DUPLICATE KEY(event_day, site_id, city_code, user_name)
PARTITION BY date_trunc('month', event_day)
DISTRIBUTED BY HASH(event_day, site_id)
PROPERTIES(
"partition_live_number" = "3" -- only retains the most recent three partitions
);

Пример 3: Предположим, вы часто запрашиваете данные по неделям. Вы можете использовать выражение секционирования time_slice() и установить столбец секционирования как event_day, а гранулярность секционирования в семь дней при создании таблицы. Данные одной недели хранятся в одной секции, и обрезка секций может использоваться для значительного повышения эффективности запросов.

CREATE TABLE site_access(
event_day DATETIME NOT NULL,
site_id INT DEFAULT '10',
city_code VARCHAR(100),
user_name VARCHAR(32) DEFAULT '',
pv BIGINT DEFAULT '0'
)
DUPLICATE KEY(event_day, site_id, city_code, user_name)
PARTITION BY time_slice(event_day, INTERVAL 7 day)
DISTRIBUTED BY HASH(event_day, site_id)

Секционирование на основе выражения столбца (начиная с версии 1.5.0)

Если вы часто запрашиваете и управляете данными определенного типа, вам нужно только указать столбец, представляющий тип, в качестве столбца секционирования. Selena автоматически создаст секции на основе значений столбца секционирования загруженных данных.

Однако в некоторых особых сценариях, например, когда таблица содержит столбец city, и вы часто запрашиваете и управляете данными на основе стран и городов. Вы должны использовать list partitioning для хранения данных нескольких городов в пределах одной страны в одной секции.

Синтаксис

PARTITION BY expression
...

expression ::=
( partition_columns )

partition_columns ::=
<column>, [ <column> [,...] ]

Параметры

partition_columns

Обязательный: ДА
Описание: Имена столбцов секционирования.

  • Значения столбца секционирования могут быть строковыми (BINARY не поддерживается), датой или datetime, целыми числами и логическими значениями. Столбец секционирования допускает значения NULL.
  • Каждая секция может содержать только данные с одинаковым значением в столбце секционирования. Чтобы включить данные с разными значениями в столбце секционирования в секцию, см. List partitioning.

Примечания по использованию

  • Во время загрузки данных Selena автоматически создает некоторые секции на основе загруженных данных, но если задание загрузки по какой-то причине завершается неудачно, секции, которые автоматически создаются Selena, не могут быть автоматически удалены.
  • Selena устанавливает максимальное количество автоматически создаваемых секций по умолчанию в 4096, что можно настроить параметром FE max_automatic_partition_number. Этот параметр может предотвратить случайное создание слишком большого количества секций.
  • Правило именования секций: если указано несколько столбцов секционирования, значения разных столбцов секционирования соединяются подчеркиванием _ в имени секции, и формат p<значение в столбце секционирования 1>_<значение в столбце секционирования 2>_.... Например, если два столбца dt и province указаны как столбцы секционирования, оба из которых являются строковыми типами, и загружается строка данных со значениями 2022-04-01 и beijing, соответствующая автоматически созданная секция называется p20220401_beijing.

Примеры

Пример 1: Предположим, вы часто запрашиваете детали биллинга центра обработки данных на основе временных диапазонов и конкретных городов. При создании таблицы вы можете использовать выражение секционирования для указания первых столбцов секционирования как dt и city. Таким образом, данные, принадлежащие одной дате и городу, направляются в одну секцию, и обрезка секций может использоваться для значительного повышения эффективности запросов.

CREATE TABLE t_recharge_detail1 (
id bigint,
user_id bigint,
recharge_money decimal(32,2),
city varchar(20) not null,
dt varchar(20) not null
)
DUPLICATE KEY(id)
PARTITION BY (dt,city)
DISTRIBUTED BY HASH(`id`);

Вставьте одну строку данных в таблицу.

INSERT INTO t_recharge_detail1 
VALUES (1, 1, 1, 'Houston', '2022-04-01');

Просмотрите секции. Результат показывает, что Selena автоматически создает секцию p20220401_Houston1 на основе загруженных данных. Во время последующей загрузки данные со значениями 2022-04-01 и Houston в столбцах секционирования dt и city хранятся в этой секции.

подсказка

Каждая секция может содержать только данные с указанным одним значением для столбца секционирования. Чтобы указать несколько значений для столбца секционирования в секции, см. List partitions.

MySQL > SHOW PARTITIONS from t_recharge_detail1\G
*************************** 1. row ***************************
PartitionId: 16890
PartitionName: p20220401_Houston
VisibleVersion: 2
VisibleVersionTime: 2023-07-19 17:24:53
VisibleVersionHash: 0
State: NORMAL
PartitionKey: dt, city
List: (('2022-04-01', 'Houston'))
DistributionKey: id
Buckets: 6
ReplicationNum: 3
StorageMedium: HDD
CooldownTime: 9999-12-31 23:59:59
LastConsistencyCheckTime: NULL
DataSize: 2.5KB
IsInMemory: false
RowCount: 1
1 row in set (0.00 sec)

Управление секциями

Загрузка данных в секции

Во время загрузки данных Selena автоматически создаст секции на основе загруженных данных и правила секционирования, определенного выражением секционирования.

Обратите внимание, что если вы используете секционирование по выражениям при создании таблицы и вам нужно использовать INSERT OVERWRITE для перезаписи данных в конкретной секции, независимо от того, была ли секция создана или нет, в настоящее время вам нужно явно предоставить диапазон секции в PARTITION(). Это отличается от [Range Partitioning../Data_distribution.mdmd#range-partitioning) или [List Partitioning../list_partitioning.mdmd), которые позволяют вам предоставлять только имя секции в PARTITION (<partition_name>).

Если вы используете выражение временной функции при создании таблицы и хотите перезаписать данные в конкретной секции, вам нужно предоставить начальную дату или datetime этой секции (гранулярность секционирования, настроенная при создании таблицы). Если секция не существует, она может быть автоматически создана во время загрузки данных.

INSERT OVERWRITE site_access1 PARTITION(event_day='2022-06-08 20:12:04')
SELECT * FROM site_access2 PARTITION(p20220608);

Если вы используете выражение столбца при создании таблицы и хотите перезаписать данные в конкретной секции, вам нужно предоставить значения столбца секционирования, которые содержит секция. Если секция не существует, она может быть автоматически создана во время загрузки данных.

INSERT OVERWRITE t_recharge_detail1 PARTITION(dt='2022-04-02',city='texas')
SELECT * FROM t_recharge_detail2 PARTITION(p20220402_texas);

Просмотр секций

Когда вы хотите просмотреть конкретную информацию об автоматически созданных секциях, вам нужно использовать оператор SHOW PARTITIONS FROM <table_name>. Оператор SHOW CREATE TABLE <table_name> возвращает только синтаксис для секционирования по выражениям, который настроен при создании таблицы.

MySQL > SHOW PARTITIONS FROM t_recharge_detail1;
+-------------+-------------------+----------------+---------------------+--------------------+--------+--------------+-----------------------------+-----------------+---------+----------------+---------------+---------------------+--------------------------+----------+------------+----------+
| PartitionId | PartitionName | VisibleVersion | VisibleVersionTime | VisibleVersionHash | State | PartitionKey | List | DistributionKey | Buckets | ReplicationNum | StorageMedium | CooldownTime | LastConsistencyCheckTime | DataSize | IsInMemory | RowCount |
+-------------+-------------------+----------------+---------------------+--------------------+--------+--------------+-----------------------------+-----------------+---------+----------------+---------------+---------------------+--------------------------+----------+------------+----------+
| 16890 | p20220401_Houston | 2 | 2023-07-19 17:24:53 | 0 | NORMAL | dt, city | (('2022-04-01', 'Houston')) | id | 6 | 3 | HDD | 9999-12-31 23:59:59 | NULL | 2.5KB | false | 1 |
| 17056 | p20220402_texas | 2 | 2023-07-19 17:27:42 | 0 | NORMAL | dt, city | (('2022-04-02', 'texas')) | id | 6 | 3 | HDD | 9999-12-31 23:59:59 | NULL | 2.5KB | false | 1 |
+-------------+-------------------+----------------+---------------------+--------------------+--------+--------------+-----------------------------+-----------------+---------+----------------+---------------+---------------------+--------------------------+----------+------------+----------+
2 rows in set (0.00 sec)

Ограничения

  • Начиная с версии 1.5.0, режим shared-data Selena поддерживает выражение временной функции. А начиная с версии 1.5.0, режим shared-data Selena дополнительно поддерживает выражение столбца.
  • В настоящее время использование CTAS для создания таблиц с настроенным секционированием по выражениям не поддерживается.
  • В настоящее время использование Spark Load для загрузки данных в таблицы, которые используют секционирование по выражениям, не поддерживается.
  • Когда оператор ALTER TABLE <table_name> DROP PARTITION <partition_name> используется для удаления секции, созданной с использованием выражения столбца, данные в секции напрямую удаляются и не могут быть восстановлены.
  • В настоящее время вы не можете создавать резервные копии и восстанавливать таблицы, созданные со стратегией секционирования по выражениям.