26.2.4 Хеширование при разбиении
Разбиение по HASH используется в первую очередь для обеспечения равномерного распределения данных по заранее определенному количеству разделов. При разбиении по диапазону или списку необходимо явно указать, в какой раздел будет помещено заданное значение столбца или набор значений столбцов; при разбиении по хешу это решение принимается за вас, и вам нужно только указать значение столбца или выражение, основанное на значении столбца, которое должно быть хешировано, и количество разделов, на которые будет разделена таблица.
Для разбиения таблицы с использованием разбиения по HASH необходимо добавить к инструкции CREATE
TABLE предложение PARTITION BY HASH
(, где expr)expr — это выражение, возвращающее целое число. Это может быть просто имя столбца, тип которого является одним из целочисленных типов MySQL. Кроме того, вы, скорее всего, захотите добавить PARTITIONS
, где numnum — это положительное целое число, представляющее количество разделов, на которые будет разделена таблица.
Для простоты таблицы в примерах ниже не используют никаких ключей. Следует учитывать, что если таблица имеет какие-либо уникальные ключи, каждый столбец, используемый в выражении разбиения для этой таблицы, должен быть частью каждого уникального ключа, включая первичный ключ. Более подробную информацию см. в разделе 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=, где cxc — некоторая отличная от нуля константа, тем лучше выражение подходит для хеширования. Это связано с тем, что чем нелинейнее выражение, тем неравномернее распределение данных по разделам, которое оно создает.
Теоретически, обрезание также возможно для выражений, включающих несколько значений столбцов, но определение подходящих выражений может быть довольно сложным и длительным. По этой причине использование выражений хеширования, включающих несколько столбцов, не особо рекомендуется.
Когда используется 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 9.2 также поддерживает разновидность разбиения по HASH, известную как линейное хеширование, которое использует более сложный алгоритм для определения расположения новых строк, вставляемых в таблицу с разбиением. Подробное описание этого алгоритма см. в разделе 26.2.4.1, «Линейное хеширование при разбиении».
Пользовательское выражение вычисляется каждый раз при вставке или обновлении записи. При определенных обстоятельствах оно также может вычисляться при удалении записей.
© 2025 Oracle
Licensed under the GPLv2 License.