22.2.6 Подразделение
Подразделение — также известное как составное разделение — это дальнейшее разделение каждой части в таблице с разделением. Рассмотрим следующее CREATE TABLE оператор:
CREATE TABLE ts (id INT, purchased DATE)
PARTITION BY RANGE( YEAR(purchased) )
SUBPARTITION BY HASH( TO_DAYS(purchased) )
SUBPARTITIONS 2 (
PARTITION p0 VALUES LESS THAN (1990),
PARTITION p1 VALUES LESS THAN (2000),
PARTITION p2 VALUES LESS THAN MAXVALUE
);
Таблица ts имеет 3 RANGE раздела. Каждый из этих разделов — p0, p1 и p2 — далее разделяется на 2 подраздела. Фактически, вся таблица разделена на 3 * 2 = 6 разделов. Однако из-за действия условия PARTITION BY RANGE первые 2 из них хранят только те записи, у которых значение меньше 1990 в столбце purchased.
В MySQL 5.7 можно подразделять таблицы, разделенные по RANGE или LIST. Подразделы могут использовать либо HASH, либо KEY разделение. Это также известно как составное разделение.
SUBPARTITION BY HASH и SUBPARTITION BY KEY обычно следуют тем же правилам синтаксиса, что и PARTITION BY HASH и PARTITION BY KEY соответственно. Исключением является то, что SUBPARTITION BY
KEY (в отличие от PARTITION BY KEY) в настоящее время не поддерживает столбец по умолчанию, поэтому столбец, используемый для этой цели, должен быть указан, даже если таблица имеет явный первичный ключ. Это известная проблема, над которой мы работаем; см. Проблемы с подразделами для получения дополнительной информации и примера.
Также можно определить подразделы явно, используя SUBPARTITION предложения для указания параметров для отдельных подразделов. Например, более подробный способ создания той же таблицы ts, как показано в предыдущем примере, будет таким:
CREATE TABLE ts (id INT, purchased DATE)
PARTITION BY RANGE( YEAR(purchased) )
SUBPARTITION BY HASH( TO_DAYS(purchased) ) (
PARTITION p0 VALUES LESS THAN (1990) (
SUBPARTITION s0,
SUBPARTITION s1
),
PARTITION p1 VALUES LESS THAN (2000) (
SUBPARTITION s2,
SUBPARTITION s3
),
PARTITION p2 VALUES LESS THAN MAXVALUE (
SUBPARTITION s4,
SUBPARTITION s5
)
);
Некоторые важные моменты синтаксиса перечислены здесь:
Каждый раздел должен иметь одинаковое количество подразделов.
-
Если вы явно определяете какие-либо подразделы, используя
SUBPARTITIONдля любого раздела таблицы с разделением, вы должны определить их все. Другими словами, следующее утверждение не выполняется:CREATE TABLE ts (id INT, purchased DATE) PARTITION BY RANGE( YEAR(purchased) ) SUBPARTITION BY HASH( TO_DAYS(purchased) ) ( PARTITION p0 VALUES LESS THAN (1990) ( SUBPARTITION s0, SUBPARTITION s1 ), PARTITION p1 VALUES LESS THAN (2000), PARTITION p2 VALUES LESS THAN MAXVALUE ( SUBPARTITION s2, SUBPARTITION s3 ) );Это утверждение все равно не выполнится, даже если оно будет включать
SUBPARTITIONS 2предложение. Каждое
SUBPARTITIONпредложение должно включать (как минимум) имя подраздела. В противном случае вы можете установить любой желаемый параметр для подраздела или позволить ему принять значение по умолчанию для этого параметра.-
Имена подразделов должны быть уникальными для всей таблицы. Например, следующее
CREATE TABLEутверждение допустимо в MySQL 5.7:CREATE TABLE ts (id INT, purchased DATE) PARTITION BY RANGE( YEAR(purchased) ) SUBPARTITION BY HASH( TO_DAYS(purchased) ) ( PARTITION p0 VALUES LESS THAN (1990) ( SUBPARTITION s0, SUBPARTITION s1 ), PARTITION p1 VALUES LESS THAN (2000) ( SUBPARTITION s2, SUBPARTITION s3 ), PARTITION p2 VALUES LESS THAN MAXVALUE ( SUBPARTITION s4, SUBPARTITION s5 ) );
Подразделы можно использовать с особенно большими MyISAM таблицами, чтобы распределить данные и индексы по многим дискам. Предположим, что у вас есть 6 дисков, смонтированных как /disk0, /disk1, /disk2 и так далее. Теперь рассмотрим следующий пример:
CREATE TABLE ts (id INT, purchased DATE)
ENGINE = MYISAM
PARTITION BY RANGE( YEAR(purchased) )
SUBPARTITION BY HASH( TO_DAYS(purchased) ) (
PARTITION p0 VALUES LESS THAN (1990) (
SUBPARTITION s0
DATA DIRECTORY = '/disk0/data'
INDEX DIRECTORY = '/disk0/idx',
SUBPARTITION s1
DATA DIRECTORY = '/disk1/data'
INDEX DIRECTORY = '/disk1/idx'
),
PARTITION p1 VALUES LESS THAN (2000) (
SUBPARTITION s2
DATA DIRECTORY = '/disk2/data'
INDEX DIRECTORY = '/disk2/idx',
SUBPARTITION s3
DATA DIRECTORY = '/disk3/data'
INDEX DIRECTORY = '/disk3/idx'
),
PARTITION p2 VALUES LESS THAN MAXVALUE (
SUBPARTITION s4
DATA DIRECTORY = '/disk4/data'
INDEX DIRECTORY = '/disk4/idx',
SUBPARTITION s5
DATA DIRECTORY = '/disk5/data'
INDEX DIRECTORY = '/disk5/idx'
)
);
В этом случае для данных и индексов каждого RANGE используется отдельный диск. Возможно множество других вариантов; другой пример может быть следующим:
CREATE TABLE ts (id INT, purchased DATE)
ENGINE = MYISAM
PARTITION BY RANGE(YEAR(purchased))
SUBPARTITION BY HASH( TO_DAYS(purchased) ) (
PARTITION p0 VALUES LESS THAN (1990) (
SUBPARTITION s0a
DATA DIRECTORY = '/disk0'
INDEX DIRECTORY = '/disk1',
SUBPARTITION s0b
DATA DIRECTORY = '/disk2'
INDEX DIRECTORY = '/disk3'
),
PARTITION p1 VALUES LESS THAN (2000) (
SUBPARTITION s1a
DATA DIRECTORY = '/disk4/data'
INDEX DIRECTORY = '/disk4/idx',
SUBPARTITION s1b
DATA DIRECTORY = '/disk5/data'
INDEX DIRECTORY = '/disk5/idx'
),
PARTITION p2 VALUES LESS THAN MAXVALUE (
SUBPARTITION s2a,
SUBPARTITION s2b
)
);
В этом случае хранение выполняется следующим образом:
-
Записи с датами
purchasedдо 1990 года занимают очень много места, поэтому разделены на 4 части, при этом отдельный диск выделен для данных и индексов для каждого из двух подразделов (s0aиs0b), составляющих разделp0. Другими словами:Данные для подраздела
s0aхранятся на/disk0.Индексы для подраздела
s0aхранятся на/disk1.Данные для подраздела
s0bхранятся на/disk2.Индексы для подраздела
s0bхранятся на/disk3.
-
Записи с датами от 1990 до 1999 года (раздел
p1) не требуют такого же пространства, как записи до 1990 года. Они разделены между 2 дисками (/disk4и/disk5), а не 4 дисками, как в случае с устаревшими записями, хранящимися вp0:Данные и индексы первого подраздела
p1(s1a) хранятся на/disk4— данные в/disk4/data, а индексы в/disk4/idx.Данные и индексы второго подраздела
p1(s1b) хранятся на/disk5— данные в/disk5/data, а индексы в/disk5/idx.
-
Записи, отражающие даты с 2000 года по настоящее время (раздел
p2), не занимают столько же места, сколько предыдущие диапазоны. В настоящее время достаточно хранить их в стандартном расположении.В будущем, когда количество покупок за десятилетие, начинающееся с 2000 года, достигнет точки, когда стандартное расположение больше не предоставляет достаточного места, соответствующие строки можно переместить с помощью оператора
ALTER TABLE ... REORGANIZE PARTITION. См. Раздел 22.3, «Управление разделением» для объяснения того, как это можно сделать.
Параметры DATA DIRECTORY и INDEX
DIRECTORY запрещены в определениях разделов, когда серверный режим SQL NO_DIR_IN_CREATE активен. В MySQL 5.7 эти параметры также запрещены при определении подразделов (ошибка #42954).
© 2025 Oracle
Licensed under the GPLv2 License.