Spec-Zone .ru
спецификации, руководства, описания, API

17.6. Ограничения и Ограничения на Разделение

17.6.1. Деля Ключи, Первичные ключи, и Уникальные ключи
17.6.2. Разделение Ограничений, Касающихся Механизмов Хранения
17.6.3. Разделение Ограничений, Касающихся Функций
17.6.4. Разделение и Блокировка

Этот раздел обсуждает текущие ограничения и ограничения на поддержку разделения MySQL.

Запрещенные конструкции. Следующие конструкции не разрешаются в разделении выражений:

Для списка функций SQL, которые разрешаются в разделении выражений, см. Раздел 17.6.3, "Деля Ограничения, Касающиеся Функций".

Арифметические и логические операторы. Использование арифметических операторов +, -, и * разрешается в разделении выражений. Однако, результатом должно быть целочисленное значение или NULL (кроме в случае [LINEAR] KEY разделение, как обсуждено в другом месте в этой главе; см. Раздел 17.2, "Деля Типы", для получения дополнительной информации).

DIV оператор также поддерживается, и / оператору не разрешают. (Ошибка #30188, Ошибка #33182)

Разрядные операторы |, &, ^, <<, >>, и ~ не разрешаются в разделении выражений.

HANDLER операторы. Ранее, HANDLER оператор не поддерживался с разделенными таблицами. Это ограничение удаляется, начинаясь с MySQL 5.7.1.

Режим SQL сервера. Таблицы, использующие определяемое пользователем разделение, не сохраняют режим SQL в действительности в то время, когда они создавались. Как обсуждено в Разделе 5.1.7, "Режимы SQL Сервера", результаты многих функций MySQL и операторов могут измениться согласно режиму SQL сервера. Поэтому, изменение в режиме SQL в любое время после создания разделенных таблиц может привести к существенным изменениям в поведении таких таблиц, и могло легко привести к повреждению или потере данных. По этим причинам строго рекомендуется, чтобы Вы никогда не изменили режим SQL сервера после создания разделенных таблиц.

Примеры. Следующие примеры иллюстрируют некоторые изменения в поведении разделенных таблиц из-за изменения в режиме SQL сервера:

  1. Обработка ошибок. Предположите, что Вы создаете разделенную таблицу, разделение которой выражения является один таким как column DIV 0 или column MOD 0, как показано здесь:

    mysql> CREATE TABLE tn (c1
                        INT)    ->     PARTITION BY LIST(1 DIV c1)
                        (    ->       PARTITION p0 VALUES IN
                        (NULL),    ->       PARTITION p1 VALUES IN
                        (1)    -> );Query OK, 0 rows affected (0.05 sec)

    Поведение значения по умолчанию для MySQL должно возвратиться NULL для результата подразделения нулем, не производя ошибок:

    mysql> SELECT @@sql_mode;+------------+| @@sql_mode |+------------+|            |+------------+1 row in set (0.00 sec)mysql> INSERT INTO tn VALUES (NULL), (0), (1);Query OK, 3 rows affected (0.00 sec)Records: 3  Duplicates: 0  Warnings: 0

    Однако, изменяя режим SQL сервера, чтобы обработать подразделение нулем, поскольку ошибка и осуществить строгую обработку ошибок вызывает то же самое INSERT оператор, чтобы перестать работать, как показано здесь:

    mysql> SET
                        sql_mode='STRICT_ALL_TABLES,ERROR_FOR_DIVISION_BY_ZERO';Query OK, 0 rows affected (0.00 sec)mysql> INSERT INTO tn VALUES (NULL), (0), (1);ERROR 1365 (22012): Division by 0
  2. Табличная доступность. Иногда изменение в режиме SQL сервера может сделать разделенные таблицы неприменимыми. Следующий CREATE TABLE оператор может быть выполнен успешно только если NO_UNSIGNED_SUBTRACTION режим в действительности:

    mysql> SELECT @@sql_mode;+------------+| @@sql_mode |+------------+|            |+------------+1 row in set (0.00 sec)mysql> CREATE TABLE tu (c1 BIGINT UNSIGNED)    ->   PARTITION BY RANGE(c1 - 10) (    ->     PARTITION p0 VALUES LESS THAN (-5),    ->     PARTITION p1 VALUES LESS THAN (0),    ->     PARTITION p2 VALUES LESS THAN (5),    ->     PARTITION p3 VALUES LESS THAN (10),    ->     PARTITION p4 VALUES LESS THAN
                        (MAXVALUE)    -> );ERROR 1563 (HY000): Partition constant is out of partition function domainmysql> SET sql_mode='NO_UNSIGNED_SUBTRACTION';Query OK, 0 rows affected (0.00 sec)mysql> SELECT @@sql_mode;+-------------------------+| @@sql_mode              |+-------------------------+| NO_UNSIGNED_SUBTRACTION |+-------------------------+1 row in set (0.00 sec)mysql> CREATE TABLE tu (c1 BIGINT UNSIGNED)    ->   PARTITION BY RANGE(c1 - 10) (    ->     PARTITION p0 VALUES LESS THAN (-5),    ->     PARTITION p1 VALUES LESS THAN (0),    ->     PARTITION p2 VALUES LESS THAN (5),    ->     PARTITION p3 VALUES LESS THAN (10),    ->     PARTITION p4 VALUES LESS THAN
                        (MAXVALUE)    -> );Query OK, 0 rows affected (0.05 sec)

    Если Вы удаляете NO_UNSIGNED_SUBTRACTION режим SQL сервера после создания tu, Вы больше не можете быть в состоянии получить доступ к этой таблице:

    mysql> SET sql_mode='';Query OK, 0 rows affected (0.00 sec)mysql> SELECT * FROM tu;ERROR 1563 (HY000): Partition constant is out of partition function domainmysql> INSERT INTO tu VALUES (20);ERROR 1563 (HY000): Partition constant is out of partition function domain

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

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

Максимальное количество разделов. В MySQL 5.7 максимальное возможное число разделов для данной таблицы 8192. Это число включает подразделы.

Если, составляя таблицы с большим количеством разделов (но меньше чем максимум), Вы встречаетесь с сообщением об ошибке тем, которое Получило ошибку... от механизма хранения: Из ресурсов, когда вводный файл, можно быть в состоянии решить проблему, увеличивая значение open_files_limit системная переменная. Однако, это зависит от операционной системы, и, возможно, не возможно или желательно на всех платформах; см. Раздел C.5.2.18, "'File'Не Найденные и Подобные Ошибки", для получения дополнительной информации. В некоторых случаях используя большие количества (сотни) разделов, возможно, также не желательны из-за других проблем, так использование большего количества разделов автоматически не приводит к лучшим результатам.

См. также операции Файловой системы.

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

Ключевые кэши на раздел. В MySQL 5.7 ключевые кэши поддерживаются для разделенного MyISAM таблицы, используя CACHE INDEX и LOAD INDEX INTO CACHE операторы. Ключевые кэши могут быть определены для один, несколько, или все разделы, и индексируют для один, несколько, или все разделы могут быть предварительно загружены в ключевые кэши.

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

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

  2. Нет InnoDB табличное определение может содержать ссылку внешнего ключа на пользовательскую разделенную таблицу; нет InnoDB таблица с определяемым пользователем разделением может содержать столбцы, на которые ссылаются внешние ключи.

Контекст ограничений, только перечисленных, включает все таблицы, которые используют InnoDB механизм хранения. CREATE TABLE и ALTER TABLE операторы, которые привели бы к таблицам, нарушающим эти ограничения, не позволяются.

ALTER TABLE ... ORDER BY. ALTER TABLE ... ORDER BY column оператор, выполненный против разделенной таблицы, вызывает упорядочивание строк только в пределах каждого раздела.

FULLTEXT индексирует. Разделенные таблицы не поддерживают FULLTEXT индексирует или ищет, даже для разделенных таблиц, использующих InnoDB или MyISAM механизм хранения.

Пространственные столбцы. Столбцы с пространственными типами данных такой как POINT или GEOMETRY не может использоваться в разделенных таблицах.

Временные таблицы. Временные таблицы не могут быть разделены. (Ошибка #17497)

Таблицы журнала. Не возможно разделить таблицы журнала; ALTER TABLE ... PARTITION BY ... оператор на такой таблице перестал работать с ошибкой.

Тип данных разделения ключа. Ключ разделения должен быть или целочисленным столбцом или выражением, которое решает к целому числу. Столбец или значение выражения могут также быть NULL. (См. Раздел 17.2.7, "Дескрипторы Разделения MySQL How NULL".)

Есть два исключения к этому ограничению:

  1. Деля [LINEAR] KEY, возможно использовать столбцы других типов как разделение ключей, потому что внутренние ключевые хеш-функции MySQL производят корректный тип данных из этих типов. Например, следующий CREATE TABLE оператор допустим:

    CREATE TABLE tkc (c1 CHAR)PARTITION BY KEY(c1)PARTITIONS 4;
  2. Деля RANGE COLUMNS или LIST COLUMNS, возможно использовать строку, DATE, и DATETIME столбцы. Например, каждый из следующих CREATE TABLE операторы допустимы:

    CREATE TABLE rc (c1 INT, c2 DATE)PARTITION BY RANGE COLUMNS(c2) (    PARTITION p0 VALUES LESS THAN('1990-01-01'),    PARTITION p1 VALUES LESS THAN('1995-01-01'),    PARTITION p2 VALUES LESS THAN('2000-01-01'),    PARTITION p3 VALUES LESS THAN('2005-01-01'),    PARTITION p4 VALUES LESS THAN(MAXVALUE));CREATE TABLE lc (c1 INT, c2 CHAR(1))PARTITION BY LIST COLUMNS(c2) (    PARTITION p0 VALUES IN('a', 'd', 'g', 'j', 'm', 'p', 's', 'v', 'y'),    PARTITION p1 VALUES IN('b', 'e', 'h', 'k', 'n', 'q', 't', 'w', 'z'),    PARTITION p2 VALUES IN('c', 'f', 'i', 'l', 'o', 'r', 'u', 'x', NULL));

Ни одно из предыдущих исключений не применяется к BLOB или TEXT типы столбца.

Подзапросы. Ключ разделения, возможно, не подзапрос, даже если тот подзапрос решает к целочисленному значению или NULL.

Проблемы с подразделами. Подразделы должны использовать HASH или KEY разделение. Только RANGE и LIST разделы могут быть подразделены; HASH и KEY разделы не могут быть подразделены.

В настоящий момент, SUBPARTITION BY KEY требует, чтобы столбец подразделения или столбцы были определены явно, в отличие от случая с PARTITION BY KEY, где это может быть опущено (когда столбец первичного ключа таблицы используется по умолчанию). Считайте таблицу создаваемой этим оператором:

CREATE TABLE ts (    id INT NOT NULL AUTO_INCREMENT PRIMARY KEY,    name VARCHAR(30));

Можно составить таблицу, имеющую те же самые столбцы, разделенные KEY, использование оператора, такого как этот:

CREATE TABLE ts (    id INT NOT NULL AUTO_INCREMENT PRIMARY KEY,    name VARCHAR(30))PARTITION BY KEY() PARTITIONS 4;        

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

CREATE TABLE ts (    id INT NOT NULL AUTO_INCREMENT PRIMARY KEY,    name VARCHAR(30))PARTITION BY KEY(id) PARTITIONS 4;        

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

mysql> CREATE TABLE ts (    ->     id INT NOT NULL AUTO_INCREMENT PRIMARY KEY,    ->     name VARCHAR(30)    -> )    -> PARTITION BY
        RANGE(id)    -> SUBPARTITION BY KEY()    -> SUBPARTITIONS 4    -> (    ->     PARTITION p0 VALUES
        LESS THAN (100),    ->     PARTITION p1 VALUES LESS THAN
        (MAXVALUE)    -> );ERROR 1064 (42000): You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near ')mysql> CREATE TABLE ts (    ->     id
        INT NOT NULL AUTO_INCREMENT PRIMARY KEY,    ->     name
        VARCHAR(30)    -> )    -> PARTITION BY RANGE(id)    -> SUBPARTITION
        BY KEY(id)    -> SUBPARTITIONS
        4    -> (    ->     PARTITION p0 VALUES LESS THAN (100),    ->     PARTITION p1 VALUES LESS THAN (MAXVALUE)    -> );Query OK, 0 rows affected (0.07 sec)

Это - известная проблема (см. Ошибку #51470).

DATA DIRECTORY и INDEX DIRECTORY опции. DATA DIRECTORY и INDEX DIRECTORY подвергаются следующим ограничениям когда использующийся с разделенными таблицами:

Восстановление и восстановление разделенных таблиц. Операторы CHECK TABLE, OPTIMIZE TABLE, ANALYZE TABLE, и REPAIR TABLE поддерживаются для разделенных таблиц.

Кроме того, можно использовать ALTER TABLE ... REBUILD PARTITION восстановить один или более разделов разделенной таблицы; ALTER TABLE ... REORGANIZE PARTITION также разделы причин, которые будут восстановлены. См. Раздел 13.1.6,"ALTER TABLE Синтаксис", для получения дополнительной информации об этих двух операторах.

mysqlcheck и myisamchk не поддерживаются с разделенными таблицами.