Spec-Zone .ru
спецификации, руководства, описания, API
|
Этот раздел обсуждает отношение разделения ключей с первичными ключами и уникальными ключами. Правило, управляющее этим отношением, может быть выражено следующим образом: Все столбцы, используемые в выражении разделения для разделенной таблицы, должны быть частью каждого уникального ключа, который может иметь таблица.
Другими словами каждый уникальный ключ на таблице должен использовать каждый столбец в выражении разделения таблицы. (Это также включает первичный ключ таблицы, так как это - по определению уникальный ключ. Этот особый случай обсуждается позже в этом разделе.) Например, каждый из следующих табличных операторов создания недопустим:
CREATE TABLE t1 ( col1 INT NOT NULL, col2 DATE NOT NULL, col3 INT NOT NULL, col4 INT NOT NULL, UNIQUE KEY (col1, col2))PARTITION BY HASH(col3)PARTITIONS 4;CREATE TABLE t2 ( col1 INT NOT NULL, col2 DATE NOT NULL, col3 INT NOT NULL, col4 INT NOT NULL, UNIQUE KEY (col1), UNIQUE KEY (col3))PARTITION BY HASH(col1 + col3)PARTITIONS 4;
В каждом случае у предложенной таблицы был бы по крайней мере один уникальный ключ, который не включает все столбцы, используемые в выражение разделения.
Каждый из следующих операторов допустим, и представляет один путь, которым соответствующий недопустимый табличный оператор создания мог быть сделан работать:
CREATE TABLE t1 ( col1 INT NOT NULL, col2 DATE NOT NULL, col3 INT NOT NULL, col4 INT NOT NULL, UNIQUE KEY (col1, col2, col3))PARTITION BY HASH(col3)PARTITIONS 4;CREATE TABLE t2 ( col1 INT NOT NULL, col2 DATE NOT NULL, col3 INT NOT NULL, col4 INT NOT NULL, UNIQUE KEY (col1, col3))PARTITION BY HASH(col1 + col3)PARTITIONS 4;
Этот пример показывает ошибку, произведенную в таких случаях:
mysql>CREATE TABLE t3 (
->col1 INT NOT NULL,
->col2 DATE NOT NULL,
->col3 INT NOT NULL,
->col4 INT NOT NULL,
->UNIQUE KEY (col1, col2),
->UNIQUE KEY (col3)
->)
->PARTITION BY HASH(col1 + col3)
->PARTITIONS 4;
ERROR 1491 (HY000): A PRIMARY KEY must include all columns in the table's partitioning function
CREATE
TABLE
оператор перестал работать потому что оба col1
и col3
включаются в предложенный ключ разделения, но ни один из этих столбцов не
является частью обоих из уникальных ключей на таблице. Это показывает одну возможную фиксацию для недопустимого
табличного определения:
mysql>CREATE TABLE t3 (
->col1 INT NOT NULL,
->col2 DATE NOT NULL,
->col3 INT NOT NULL,
->col4 INT NOT NULL,
->UNIQUE KEY (col1, col2, col3),
->UNIQUE KEY (col3)
->)
->PARTITION BY HASH(col3)
->PARTITIONS 4;
Query OK, 0 rows affected (0.05 sec)
В этом случае, предложенный ключ разделения col3
часть обоих уникальных ключей, и
табличный оператор создания успешно выполняется.
Следующая таблица не может быть разделена вообще, потому что нет никакого способа включать в ключ разделения любые столбцы, которые принадлежат обоим уникальным ключам:
CREATE TABLE t4 ( col1 INT NOT NULL, col2 INT NOT NULL, col3 INT NOT NULL, col4 INT NOT NULL, UNIQUE KEY (col1, col3), UNIQUE KEY (col2, col4));
Так как каждый первичный ключ является по определению уникальным ключом, это ограничение также включает первичный ключ таблицы, если у этого есть тот. Например, следующие два оператора недопустимы:
CREATE TABLE t5 ( col1 INT NOT NULL, col2 DATE NOT NULL, col3 INT NOT NULL, col4 INT NOT NULL, PRIMARY KEY(col1, col2))PARTITION BY HASH(col3)PARTITIONS 4;CREATE TABLE t6 ( col1 INT NOT NULL, col2 DATE NOT NULL, col3 INT NOT NULL, col4 INT NOT NULL, PRIMARY KEY(col1, col3), UNIQUE KEY(col2))PARTITION BY HASH( YEAR(col2) )PARTITIONS 4;
В обоих случаях первичный ключ не включает все столбцы, на которые ссылаются в выражение разделения. Однако, оба из следующих двух операторов допустимы:
CREATE TABLE t7 ( col1 INT NOT NULL, col2 DATE NOT NULL, col3 INT NOT NULL, col4 INT NOT NULL, PRIMARY KEY(col1, col2))PARTITION BY HASH(col1 + YEAR(col2))PARTITIONS 4;CREATE TABLE t8 ( col1 INT NOT NULL, col2 DATE NOT NULL, col3 INT NOT NULL, col4 INT NOT NULL, PRIMARY KEY(col1, col2, col4), UNIQUE KEY(col2, col1))PARTITION BY HASH(col1 + YEAR(col2))PARTITIONS 4;
Если у таблицы нет никаких уникальных ключей — это включает наличие никакого первичного ключа — тогда, это ограничение не применяется, и можно использовать любой столбец или столбцы в выражении разделения, пока тип столбца является совместимым с типом разделения.
По той же самой причине невозможно позже добавить уникальный ключ к разделенной таблице, если ключ не включает все столбцы, используемые выражением разделения таблицы. Считайте разделенную таблицу создаваемой как показано здесь:
mysql>CREATE TABLE t_no_pk (c1 INT, c2 INT)
->PARTITION BY RANGE(c1) (
->PARTITION p0 VALUES LESS THAN (10),
->PARTITION p1 VALUES LESS THAN (20),
->PARTITION p2 VALUES LESS THAN (30),
->PARTITION p3 VALUES LESS THAN (40)
->);
Query OK, 0 rows affected (0.12 sec)
Возможно добавить первичный ключ к t_no_pk
использование любого из них ALTER TABLE
операторы:
# possible PKmysql>ALTER TABLE t_no_pk ADD PRIMARY KEY(c1);
Query OK, 0 rows affected (0.13 sec)Records: 0 Duplicates: 0 Warnings: 0# drop this PKmysql>ALTER TABLE t_no_pk DROP PRIMARY KEY;
Query OK, 0 rows affected (0.10 sec)Records: 0 Duplicates: 0 Warnings: 0# use another possible PKmysql>ALTER TABLE t_no_pk ADD PRIMARY KEY(c1, c2);
Query OK, 0 rows affected (0.12 sec)Records: 0 Duplicates: 0 Warnings: 0# drop this PKmysql>ALTER TABLE t_no_pk DROP PRIMARY KEY;
Query OK, 0 rows affected (0.09 sec)Records: 0 Duplicates: 0 Warnings: 0
Однако, следующие сбои оператора, потому что c1
часть ключа разделения, но не часть
предложенного первичного ключа:
# fails with error 1503mysql> ALTER TABLE t_no_pk
ADD PRIMARY KEY(c2);
ERROR 1503 (HY000): A PRIMARY KEY must include all columns in the table's partitioning function
С тех пор t_no_pk
имеет только c1
в его выражении
разделения, пытаясь к включению уникального ключа c2
один сбои. Однако, можно
добавить уникальный ключ, который использует обоих c1
и c2
.
Эти правила также применяются к существующим неразделенным таблицам, которые Вы желаете к использованию раздела
ALTER TABLE ... PARTITION BY
.
Рассмотрите таблицу np_pk
создаваемый как показано здесь:
mysql>CREATE TABLE np_pk (
->id INT NOT NULL AUTO_INCREMENT,
->name VARCHAR(50),
->added DATE,
->PRIMARY KEY (id)
->);
Query OK, 0 rows affected (0.08 sec)
Следующий ALTER TABLE
оператор перестал работать с ошибкой, потому что added
столбец не является частью
любого уникального ключа в таблице:
mysql>ALTER TABLE np_pk
->PARTITION BY HASH( TO_DAYS(added) )
->PARTITIONS 4;
ERROR 1503 (HY000): A PRIMARY KEY must include all columns in the table's partitioning function
Однако, этот оператор, используя id
столбец для столбца разделения допустим, как
показано здесь:
mysql>ALTER TABLE np_pk
->PARTITION BY HASH(id)
->PARTITIONS 4;
Query OK, 0 rows affected (0.11 sec)Records: 0 Duplicates: 0 Warnings: 0
В случае np_pk
, единственный столбец, который может использоваться в качестве части
выражения разделения, id
; если Вы хотите разделить эту таблицу, используя
какой-либо другой столбец или столбцы в выражении разделения, следует сначала изменить таблицу, или добавляя
требуемый столбец или столбцы к первичному ключу, или отбрасывая первичный ключ в целом.