MySQL分区/分区的限制和限制/分区键、主键和唯一键

6.1分区键、主键和唯一键

本节讨论分区键与主键和唯一键的关系。控制此关系的规则可以表示为:分区表的分区表达式中使用的所有列必须是该表可能具有的每个唯一键的一部分。

换句话说,表上的每个唯一键都必须使用表分区表达式中的每一列. (这还包括表的主键,因为根据定义它是唯一键。此特定情况将在本节稍后讨论。)例如,以下每个表创建语句都是无效的:

创建表t1(col1 INT NOT NULL,col2 DATE NOT NULL,col3 INT NOT NULL,col4 INT NOT NULL,UNIQUE KEY(col1,col2))按哈希(col3)分区4分区;按哈希(col1+col3)分区4创建表t2(col1 INT NOT NULL,col2 DATE NOT NULL,col3 INT NOT NULL,col4 INT NOT NULL,UNIQUE KEY(col1),UNIQUE KEY(col3))分区;

在每种情况下,建议的表都至少有一个唯一键,该键不包括分区表达式中使用的所有列。

以下每一条语句都是有效的,并表示相应的无效表创建语句的一种工作方式:

创建表t1(col1 INT NOT NULL,col2 DATE NOT NULL,col3 INT NOT NULL,col4 INT NOT NULL,UNIQUE KEY(col1,col2,col3))按哈希(col3)分区4分区;按哈希(col1+col3)分区4创建表t2(col1 INT NOT NULL,col2 DATE NOT NULL,col3 INT NOT NULL,col4 INT NOT NULL,UNIQUE KEY(col1,col3))分区;

此示例显示了在这种情况下产生的错误:

mysql>创建表t3(->col1 INT NOT NULL,-->col2 DATE NOT NULL,-->col3 INT NOT NULL,-->col4 INT NOT NULL,-->唯一键(col1,col2),->唯一键(col3)->)->)->按哈希分区(col1+col3)->分区4;错误1491(HY000):主键必须包含表分区函数中的所有列

这个创建表语句失败,因为列1col3公司包含在建议的分区键中,但这两列都不是表上两个唯一键的一部分。这显示了对无效表定义的一种可能的修复方法:

mysql>创建表t3(->col1 INT NOT NULL,->col2 DATE NOT NULL,->col3 INT NOT NULL,->col4 INT NOT NULL,->唯一键(col1,col2,col3),->唯一键(col3)->)->按哈希分区(col3)->分区4;查询正常,0行受影响(0.05秒)

在这种情况下,建议的分区键col3公司是两个唯一键的一部分,并且表创建语句成功。

下表根本无法分区,因为无法在分区键中包含属于两个唯一键的任何列:

创建表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));

由于根据定义,每个主键都是唯一的键,因此此限制还包括表的主键(如果有主键的话)。例如,下面两个语句无效:

创建表t5(col1 INT NOT NULL,col2 DATE NOT NULL,col3 INT NOT NULL,col4 INT NOT NULL,PRIMARY KEY(col1,col2))按哈希(col3)分区4分区;创建表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;

在这两种情况下,主键不包括分区表达式中引用的所有列。但是,下面两个语句都是有效的:

创建表t7(col1 INT NOT NULL,col2 DATE NOT NULL,col3 INT NOT NULL,col4 INT NOT NULL,PRIMARY KEY(col1,col2))按哈希(col1+YEAR(col2))分区4分区;创建表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))按哈希(col1+YEAR(col2))分区4分区;

如果表没有唯一键(包括没有主键),则此限制不适用,只要列类型与分区类型兼容,就可以使用分区表达式中的任何列。

出于同样的原因,以后不能将唯一键添加到分区表中,除非该键包含表的分区表达式使用的所有列。考虑如下所示创建的分区表:

mysql>创建表t_no_pk(c1 INT,c2 INT)->分区范围(c1)(->分区p0值小于(10),->分区p1值小于(20),->分区p2值小于(30),->分区p3值小于(40)->);查询正常,0行受影响(0.12秒)

可以将主键添加到没有主键使用其中一个更改表格声明:

#可能PK mysql>ALTER TABLE t\u no\u PK ADD PRIMARY KEY(c1);查询确定,0行受影响(0.13秒)记录:0重复:0警告:0#drop this PK mysql>ALTER TABLE tŠu noŠPK drop PRIMARY KEY;查询确定,0行受影响(0.10秒)记录:0重复:0警告:0#使用另一个可能的PK mysql>ALTER TABLE t_no_PK ADD主键(c1,c2);查询确定,0行受影响(0.12秒)记录:0重复:0警告:0#drop this PK mysql>ALTER TABLE tŠu noŠPK drop PRIMARY KEY;查询正常,0行受影响(0.09秒)记录:0重复:0警告:0

但是,下一个语句失败了,因为c1类是分区键的一部分,但不是建议的主键的一部分:

#失败,错误1503 mysql>ALTER TABLE t\u no\u pk ADD PRIMARY KEY(c2);错误1503(HY000):主键必须包含表分区函数中的所有列

没有主键只有c1类在其分区表达式中,尝试在c2级独自失败。但是,您可以添加一个同时使用这两个属性的唯一键c1类c2级.

这些规则也适用于要使用分区的现有非分区表更改表。。。分区依据. 考虑一张桌子np\U主键创建如下所示:

mysql>CREATE TABLE np_pk(->id INT NOT NULL AUTO_INCREMENT,->name VARCHAR(50),->added DATE,->主键(id)->);查询正常,0行受影响(0.08秒)

以下更改表格语句失败并出现错误,因为补充列不是表中任何唯一键的一部分:

mysql>ALTER TABLE np \u pk->PARTITION BY HASH(TO \u DAYS(added))->分区4;错误1503(HY000):主键必须包含表分区函数中的所有列

但是,此语句使用身份证件分区列的列是有效的,如下所示:

mysql>ALTER TABLE np\u pk->PARTITION BY HASH(id)->分区4;查询正常,0行受影响(0.11秒)记录:0重复:0警告:0

如果是np\U主键,唯一可以用作分区表达式一部分的列是身份证件; 如果要使用分区表达式中的任何其他列对此表进行分区,则必须首先修改该表,方法是将所需的列添加到主键中,或者将主键一起删除。