Spec-Zone .ru
спецификации, руководства, описания, API
|
Разделение в MySQL не делает ничего, чтобы отвергнуть NULL
как значение выражения
разделения, является ли это значением столбца или значением предоставленного пользователем выражения. Даже при
том, что разрешается использовать NULL
как значение выражения, которое должно иначе
привести к целому числу, важно иметь в виду это NULL
не число. Обработки реализации
разделения MySQL NULL
как являющийся меньше чем любой не -NULL
значение, так же, как ORDER BY
делает.
Это означает ту обработку NULL
изменяется между разделением различных типов, и
может произвести поведение, которое Вы не ожидаете, не готовитесь ли Вы к этому. Этот являющийся имеющим место,
мы обсуждаем в этом разделе, как каждый MySQL, делящий тип, обрабатывает NULL
значения, определяя раздел, в котором строка должна быть сохранена, и предоставить примеры каждому.
Обработка NULL
с RANGE
разделение. Если Вы
вставляете строку в таблицу, разделенную RANGE
так, что значение столбца,
используемое, чтобы определить раздел, NULL
, строка вставляется в самый низкий
раздел. Считайте эти две таблицы в базе данных названными p
, создаваемый следующим
образом:
mysql>CREATE TABLE t1 (
->c1 INT,
->c2 VARCHAR(20)
->)
->PARTITION BY RANGE(c1) (
->PARTITION p0 VALUES LESS THAN (0),
->PARTITION p1 VALUES LESS THAN (10),
->PARTITION p2 VALUES LESS THAN MAXVALUE
->);
Query OK, 0 rows affected (0.09 sec)mysql>CREATE TABLE t2 (
->c1 INT,
->c2 VARCHAR(20)
->)
->PARTITION BY RANGE(c1) (
->PARTITION p0 VALUES LESS THAN (-5),
->PARTITION p1 VALUES LESS THAN (0),
->PARTITION p2 VALUES LESS THAN (10),
->PARTITION p3 VALUES LESS THAN MAXVALUE
->);
Query OK, 0 rows affected (0.09 sec)
Можно видеть разделы, создаваемые этими двумя CREATE
TABLE
операторы используя следующий запрос против PARTITIONS
таблица в INFORMATION_SCHEMA
база данных:
mysql>SELECT TABLE_NAME, PARTITION_NAME, TABLE_ROWS, AVG_ROW_LENGTH, DATA_LENGTH
>FROM INFORMATION_SCHEMA.PARTITIONS
>WHERE TABLE_SCHEMA = 'p' AND TABLE_NAME LIKE 't_';
+------------+----------------+------------+----------------+-------------+| TABLE_NAME | PARTITION_NAME | TABLE_ROWS | AVG_ROW_LENGTH | DATA_LENGTH |+------------+----------------+------------+----------------+-------------+| t1 | p0 | 0 | 0 | 0 || t1 | p1 | 0 | 0 | 0 || t1 | p2 | 0 | 0 | 0 || t2 | p0 | 0 | 0 | 0 || t2 | p1 | 0 | 0 | 0 || t2 | p2 | 0 | 0 | 0 || t2 | p3 | 0 | 0 | 0 |+------------+----------------+------------+----------------+-------------+7 rows in set (0.00 sec)
(Для получения дополнительной информации об этой таблице, см. Раздел
20.14," INFORMATION_SCHEMA PARTITIONS
Таблица".) Теперь позволяют нам
заполнять каждую из этих таблиц с единственной строкой, содержащей a NULL
в
столбце, используемом в качестве ключа разделения, и, проверяют, что строки были вставлены, используя пару SELECT
операторы:
mysql>INSERT INTO t1 VALUES (NULL, 'mothra');
Query OK, 1 row affected (0.00 sec)mysql>INSERT INTO t2 VALUES (NULL, 'mothra');
Query OK, 1 row affected (0.00 sec)mysql>SELECT * FROM t1;
+------+--------+| id | name |+------+--------+| NULL | mothra |+------+--------+1 row in set (0.00 sec)mysql>SELECT * FROM t2;
+------+--------+| id | name |+------+--------+| NULL | mothra |+------+--------+1 row in set (0.00 sec)
Можно видеть, против которого разделы используются, чтобы сохранить вставленные строки, запуская повторно
предыдущий запрос INFORMATION_SCHEMA.PARTITIONS
и осмотр вывода:
mysql>SELECT TABLE_NAME, PARTITION_NAME, TABLE_ROWS, AVG_ROW_LENGTH, DATA_LENGTH
>FROM INFORMATION_SCHEMA.PARTITIONS
>WHERE TABLE_SCHEMA = 'p' AND TABLE_NAME LIKE 't_';
+------------+----------------+------------+----------------+-------------+| TABLE_NAME | PARTITION_NAME | TABLE_ROWS | AVG_ROW_LENGTH | DATA_LENGTH |+------------+----------------+------------+----------------+-------------+| t1 | p0 | 1 | 20 | 20 || t1 | p1 | 0 | 0 | 0 || t1 | p2 | 0 | 0 | 0 || t2 | p0 | 1 | 20 | 20 || t2 | p1 | 0 | 0 | 0 || t2 | p2 | 0 | 0 | 0 || t2 | p3 | 0 | 0 | 0 |+------------+----------------+------------+----------------+-------------+7 rows in set (0.01 sec)
Можно также демонстрировать, что эти строки были сохранены в самом низком разделе каждой таблицы, отбрасывая эти
разделы, и затем запуская повторно SELECT
операторы:
mysql>ALTER TABLE t1 DROP PARTITION p0;
Query OK, 0 rows affected (0.16 sec)mysql>ALTER TABLE t2 DROP PARTITION p0;
Query OK, 0 rows affected (0.16 sec)mysql>SELECT * FROM t1;
Empty set (0.00 sec)mysql>SELECT * FROM t2;
Empty set (0.00 sec)
(Для получения дополнительной информации по ALTER TABLE ... DROP PARTITION
, см. Раздел 13.1.7,"ALTER TABLE
Синтаксис".)
NULL
также обрабатывается таким образом для того, чтобы разделить выражения тот SQL
использования функции. Предположите, что мы определяем таблицу, используя a CREATE TABLE
оператор, такой как этот:
CREATE TABLE tndate ( id INT, dt DATE)PARTITION BY RANGE( YEAR(dt) ) ( PARTITION p0 VALUES LESS THAN (1990), PARTITION p1 VALUES LESS THAN (2000), PARTITION p2 VALUES LESS THAN MAXVALUE);
Как с другими функциями MySQL, YEAR(NULL)
возвраты NULL
. Строка с a dt
значение столбца NULL
обрабатывается, как если бы выражение разделения, оцененное к значению
меньше чем любое другое значение, и так, вставляется в раздел p0
.
Обработка NULL
с LIST
разделение. Таблица,
которая делится LIST
признает NULL
значения, если и
только если один из его разделов определяется, используя тот список значения, который содержит NULL
. Обратное из этого то, что таблица, разделенная LIST
который явно не использует NULL
в значении
список отклоняет строки, приводящие к a NULL
значение для выражения разделения, как
показано в этом примере:
mysql>CREATE TABLE ts1 (
->c1 INT,
->c2 VARCHAR(20)
->)
->PARTITION BY LIST(c1) (
->PARTITION p0 VALUES IN (0, 3, 6),
->PARTITION p1 VALUES IN (1, 4, 7),
->PARTITION p2 VALUES IN (2, 5, 8)
->);
Query OK, 0 rows affected (0.01 sec)mysql>INSERT INTO ts1 VALUES (9, 'mothra');
ERROR 1504 (HY000): Table has no partition for value 9mysql>INSERT INTO ts1 VALUES (NULL, 'mothra');
ERROR 1504 (HY000): Table has no partition for value NULL
Только строки, имеющие a c1
значение между 0
и 8
включительно может быть вставлен в ts1
. NULL
падения вне этого диапазона, точно так же как число 9
. Мы можем составить таблицы ts2
и ts3
наличие значения перечисляет содержащий NULL
, как
показано здесь:
mysql> CREATE TABLE ts2 ( -> c1 INT, -> c2 VARCHAR(20) -> ) -> PARTITION BY LIST(c1) ( -> PARTITION p0 VALUES IN (0, 3, 6), -> PARTITION p1 VALUES IN (1, 4, 7), -> PARTITION p2 VALUES IN (2, 5, 8), -> PARTITION p3 VALUES IN (NULL) -> );Query OK, 0 rows affected (0.01 sec)mysql> CREATE TABLE ts3 ( -> c1 INT, -> c2 VARCHAR(20) -> ) -> PARTITION BY LIST(c1) ( -> PARTITION p0 VALUES IN (0, 3, 6), -> PARTITION p1 VALUES IN (1, 4, 7, NULL), -> PARTITION p2 VALUES IN (2, 5, 8) -> );Query OK, 0 rows affected (0.01 sec)
Когда определение значения перечисляет для того, чтобы разделить, Вы можете (и если) обработка NULL
так же, как Вы были бы любое другое значение. Например, оба VALUES IN (NULL)
и VALUES IN (1, 4, 7, NULL)
допустимы,
как VALUES IN (1, NULL, 4, 7)
, VALUES IN (NULL, 1, 4,
7)
, и так далее. Можно вставить наличие строки NULL
для столбца c1
в каждую из таблиц ts2
и ts3
:
mysql>INSERT INTO ts2 VALUES (NULL, 'mothra');
Query OK, 1 row affected (0.00 sec)mysql>INSERT INTO ts3 VALUES (NULL, 'mothra');
Query OK, 1 row affected (0.00 sec)
Выпуская соответствующий запрос против INFORMATION_SCHEMA.PARTITIONS
, можно определить, какие разделы использовались,
чтобы сохранить строки, только вставленные (мы принимаем, как в предыдущих примерах, что разделенные таблицы
создавались в p
база данных):
mysql>SELECT TABLE_NAME, PARTITION_NAME, TABLE_ROWS, AVG_ROW_LENGTH, DATA_LENGTH
>FROM INFORMATION_SCHEMA.PARTITIONS
>WHERE TABLE_SCHEMA = 'p' AND TABLE_NAME LIKE 'ts_';
+------------+----------------+------------+----------------+-------------+| TABLE_NAME | PARTITION_NAME | TABLE_ROWS | AVG_ROW_LENGTH | DATA_LENGTH |+------------+----------------+------------+----------------+-------------+| ts2 | p0 | 0 | 0 | 0 || ts2 | p1 | 0 | 0 | 0 || ts2 | p2 | 0 | 0 | 0 || ts2 | p3 | 1 | 20 | 20 || ts3 | p0 | 0 | 0 | 0 || ts3 | p1 | 1 | 20 | 20 || ts3 | p2 | 0 | 0 | 0 |+------------+----------------+------------+----------------+-------------+7 rows in set (0.01 sec)
Как показано ранее в этом разделе, можно также проверить, какие разделы использовались для того, чтобы сохранить
строки, удаляя эти разделы и затем выполняя a SELECT
.
Обработка NULL
с HASH
и KEY
разделение. NULL
обрабатывается несколько
по-другому для таблиц, разделенных HASH
или KEY
. В
этих случаях, любое выражение раздела, которое приводит к a NULL
значение
обрабатывается, как если бы его возвращаемое значение было нулем. Мы можем проверить это поведение, исследуя
эффекты на файловую систему составления таблицы, разделенной HASH
и заполнение
этого с записью, содержащей соответствующие значения. Предположите, что у Вас есть таблица th
(также в p
база данных) создаваемое использование
следующего оператора:
mysql>CREATE TABLE th (
->c1 INT,
->c2 VARCHAR(20)
->)
->PARTITION BY HASH(c1)
->PARTITIONS 2;
Query OK, 0 rows affected (0.00 sec)
Разделы, принадлежащие этой таблице, могут быть просмотрены, используя запрос, показанный здесь:
mysql> SELECT TABLE_NAME,PARTITION_NAME,TABLE_ROWS,AVG_ROW_LENGTH,DATA_LENGTH > FROM INFORMATION_SCHEMA.PARTITIONS > WHERE TABLE_SCHEMA = 'p' AND TABLE_NAME ='th';+------------+----------------+------------+----------------+-------------+| TABLE_NAME | PARTITION_NAME | TABLE_ROWS | AVG_ROW_LENGTH | DATA_LENGTH |+------------+----------------+------------+----------------+-------------+| th | p0 | 0 | 0 | 0 || th | p1 | 0 | 0 | 0 |+------------+----------------+------------+----------------+-------------+2 rows in set (0.00 sec)
Отметьте это TABLE_ROWS
поскольку каждый раздел 0. Теперь вставьте две строки в
th
чей c1
значения столбцов NULL
и 0, и проверяют, что эти строки были вставлены, как показано здесь:
mysql>INSERT INTO th VALUES (NULL, 'mothra'), (0, 'gigan');
Query OK, 1 row affected (0.00 sec)mysql>SELECT * FROM th;
+------+---------+| c1 | c2 |+------+---------+| NULL | mothra |+------+---------+| 0 | gigan |+------+---------+2 rows in set (0.01 sec)
Вспомните это для любого целого числа N
, значение NULL MOD
всегда N
NULL
. Для таблиц, которые делятся HASH
или KEY
, этот результат лечат от того, что он определил корректный раздел как 0
. Проверка INFORMATION_SCHEMA.PARTITIONS
таблица еще раз, мы можем видеть, что обе строки
были вставлены в раздел p0
:
mysql>SELECT TABLE_NAME, PARTITION_NAME, TABLE_ROWS, AVG_ROW_LENGTH, DATA_LENGTH
>FROM INFORMATION_SCHEMA.PARTITIONS
>WHERE TABLE_SCHEMA = 'p' AND TABLE_NAME ='th';
+------------+----------------+------------+----------------+-------------+| TABLE_NAME | PARTITION_NAME | TABLE_ROWS | AVG_ROW_LENGTH | DATA_LENGTH |+------------+----------------+------------+----------------+-------------+| th | p0 | 2 | 20 | 20 || th | p1 | 0 | 0 | 0 |+------------+----------------+------------+----------------+-------------+2 rows in set (0.00 sec)
Если Вы повторяете это использование в качестве примера PARTITION BY KEY
вместо
PARTITION BY HASH
в определении таблицы можно проверить легко это NULL
также обрабатывается как 0 для этого типа разделения.