Spec-Zone.ru › MySQL 8.4

26.2.4 Разбиение по хешу

  • 26.2.4.1 Разбиение по линейному хешу

Разбиение по HASH используется в основном для обеспечения равномерного распределения данных по заданному числу разделов. При разбиении по диапазону или списку вы должны явно указать, в какой раздел должен храниться заданный столбец или набор значений столбцов; при разбиении по хешу это решение принимается за вас, и вам нужно только указать значение столбца или выражение, основанное на значении столбца, которое должно быть хешировано, и количество разделов, на которые должна быть разделена таблицa.

Для разбиения таблицы с помощью разбиения по HASH необходимо добавить в оператор CREATE TABLE предложение PARTITION BY HASH (expr), где expr — это выражение, возвращающее целое число. Это может быть просто имя столбца, тип которого является одним из целочисленных типов MySQL. Кроме того, вы, скорее всего, захотите последовать этому PARTITIONS num, где num — положительное целое число, представляющее количество разделов, на которые должна быть разделена таблица.

Примечание

Для простоты в последующих примерах таблицы не используют ключи. Вы должны знать, что если таблица имеет уникальные ключи, каждый столбец, используемый в выражении разбиения для этой таблицы, должен быть частью каждого уникального ключа, включая первичный ключ. Дополнительную информацию см. в разделе 26.6.1 «Ключи разбиения, первичные ключи и уникальные ключи».

Следующее оператор создает таблицу, которая использует хэширование по столбцу store_id и разделена на 4 раздела:

CREATE TABLE employees (
    id INT NOT NULL,
    fname VARCHAR(30),
    lname VARCHAR(30),
    hired DATE NOT NULL DEFAULT '1970-01-01',
    separated DATE NOT NULL DEFAULT '9999-12-31',
    job_code INT,
    store_id INT
)
PARTITION BY HASH(store_id)
PARTITIONS 4;

Если вы не включите предложение PARTITIONS, количество разделов по умолчанию будет 1; использование ключевого слова PARTITIONS без числа после него приводит к синтаксической ошибке.

Вы также можете использовать выражение SQL, возвращающее целое число для expr. Например, вы можете разбить данные по году, в который был нанят сотрудник. Это можно сделать следующим образом:

CREATE TABLE employees (
    id INT NOT NULL,
    fname VARCHAR(30),
    lname VARCHAR(30),
    hired DATE NOT NULL DEFAULT '1970-01-01',
    separated DATE NOT NULL DEFAULT '9999-12-31',
    job_code INT,
    store_id INT
)
PARTITION BY HASH( YEAR(hired) )
PARTITIONS 4;

expr должно возвращать неконстантное, неслучайное целое значение (другими словами, оно должно быть переменным, но детерминированным) и не должно содержать запрещённых конструкций, как описано в разделе 26.6 «Ограничения и ограничения разбиения». Вы также должны помнить, что это выражение вычисляется каждый раз при вставке или обновлении строки (или, возможно, при удалении); это означает, что очень сложные выражения могут привести к проблемам производительности, особенно при выполнении операций (таких как пакетные вставки), затрагивающих большое количество строк одновременно.

Наиболее эффективная функция хэширования — это функция, которая работает с одним столбцом таблицы и значение которой увеличивается или уменьшается последовательно со значением столбца, поскольку это позволяет выполнять «обрезку» диапазонов разделов. То есть, чем ближе выражение изменяется со значением столбца, на основе которого оно основано, тем эффективнее MySQL может использовать выражение для разбиения по хешу.

Например, если date_col — столбец типа DATE, то выражение TO_DAYS(date_col) изменяется прямо пропорционально значению date_col, потому что при каждом изменении значения date_col значение выражения изменяется последовательно. Изменение выражения YEAR(date_col) относительно date_col не так прямо, как у TO_DAYS(date_col), потому что не каждое возможное изменение в date_col приводит к эквивалентному изменению в YEAR(date_col). Тем не менее, YEAR(date_col) является хорошим кандидатом для функции хеширования, потому что она изменяется прямо пропорционально части date_col, и нет возможных изменений в date_col, которые вызывают непропорциональное изменение в YEAR(date_col).

В качестве контраста, предположим, что у вас есть столбец с именем int_col, тип которого INT. Теперь рассмотрим выражение POW(5-int_col,3) + 6. Это был бы плохой выбор для функции хеширования, потому что изменение значения int_col не гарантирует пропорциональное изменение значения выражения. Изменение значения int_col на заданное значение может привести к существенно отличающимся изменениям в значении выражения. Например, изменение int_col с 5 на 6 приводит к изменению -1 в значении выражения, но изменение значения int_col с 6 на 7 приводит к изменению -7 в значении выражения.

Другими словами, чем ближе график значения столбца по отношению к значению выражения следует прямой линии, заданной уравнением y=cx, где c — некоторая ненулевая константа, тем лучше выражение подходит для хэширования. Это связано с тем, что чем более нелинейным является выражение, тем более неравномерное распределение данных по разделам оно создаёт.

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

Когда используется PARTITION BY HASH, движок хранения определяет, какой раздел из num разделов использовать, основываясь на модуле результата выражения. Другими словами, для данного выражения expr раздел, в котором хранится запись, имеет номер N, где N = MOD(expr, num). Предположим, что таблица t1 определена следующим образом, так что у неё 4 раздела:

CREATE TABLE t1 (col1 INT, col2 CHAR(5), col3 DATE)
    PARTITION BY HASH( YEAR(col3) )
    PARTITIONS 4;

Если вы вставляете запись в t1, значение col3 которой равно '2005-09-15', то раздел, в котором она хранится, определяется следующим образом:

MOD(YEAR('2005-09-01'),4)
=  MOD(2005,4)
=  1

MySQL 8.4 также поддерживает вариант разбиения по HASH, известный как линейное хэширование, который использует более сложный алгоритм для определения размещения новых строк, вставленных в разбиение таблицы. Описание этого алгоритма см. в разделе 26.2.4.1 «Линейное хэширование».

Выражение, заданное пользователем, вычисляется каждый раз при вставке или обновлении записи. Оно также может — в зависимости от обстоятельств — вычисляться при удалении записей.

© 2025 Oracle
Licensed under the GPLv2 License.
https://docs.oracle.com/cd/E17952_01/mysql-8.4-en/partitioning-hash.html

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API