22.2.5 KEY 分区
按键分区类似于按哈希分区,除了在哈希分区采用用户定义的 table 达式的情况下,用于键分区的哈希函数由 MySQL 服务器提供。 NDB Cluster 为此使用MD5();对于使用其他存储引擎的 table,服务器使用自己的内部哈希函数,该函数基于与PASSWORD()相同的算法。
CREATE TABLE ... PARTITION BY KEY
的语法规则类似于创建由哈希分区的 table 的语法规则。主要区别如下:
-
使用
KEY
而不是HASH
。 -
KEY
仅接受零个或多个列名的列 table。如果 table 有一个主键,则用作分区键的任何列都必须包含 table 的主键的一部分或全部。如果没有将列名指定为分区键,则使用 table 的主键(如果有)。例如,以下CREATE TABLE语句在 MySQL 5.7 中有效:
CREATE TABLE k1 (
id INT NOT NULL PRIMARY KEY,
name VARCHAR(20)
)
PARTITION BY KEY()
PARTITIONS 2;
如果没有主键,但是有一个唯一键,则将唯一键用于分区键:
CREATE TABLE k1 (
id INT NOT NULL,
name VARCHAR(20),
UNIQUE KEY (id)
)
PARTITION BY KEY()
PARTITIONS 2;
但是,如果唯一键列未定义为NOT NULL
,则前一条语句将失败。
在这两种情况下,分区键都是id
列,即使未在显示创建 table的输出或INFORMATION_SCHEMA.PARTITIONStable 的PARTITION_EXPRESSION
列中显示。
与其他分区类型不同,用于按KEY
进行分区的列不限于整数或NULL
值。例如,以下CREATE TABLE语句有效:
CREATE TABLE tm1 (
s1 CHAR(32) PRIMARY KEY
)
PARTITION BY KEY(s1)
PARTITIONS 10;
如果要指定其他分区类型,则前面的语句无效。 (在这种情况下,仅使用PARTITION BY KEY()
也是有效的,并且具有与PARTITION BY KEY(s1)
相同的效果,因为s1
是 table 的主键.)
有关此问题的其他信息,请参见第 22.6 节“分区的限制和限制”。
分区键不支持带有索引前缀的列。这意味着CHAR,VARCHAR,BINARY和VARBINARY列可以在分区键中使用,只要它们不使用前缀即可。因为必须在索引定义中为BLOB和TEXT列指定前缀,所以无法在分区键中使用这两种类型的列。在 MySQL 5.7 中,创建,更改或升级分区 table 时允许使用带有前缀的列,即使它们不包含在 table 的分区键中也是如此。这是 MySQL 5.7 中的一个已知问题,而 MySQL 8.0 中已解决此问题,该行为已被弃用,并且在这些情况下尝试使用此类列时,服务器会显示适当的警告或错误。有关更多信息和示例,请参见键分区不支持列索引前缀。
Note
Important
对于键分区 table,您无法执行ALTER TABLE DROP PRIMARY KEY
,因为这样做会生成错误 ERROR 1466(HY000):在 table 中找不到分区函数的字段列 table 中的字段。对于由KEY
分区的 NDB 群集 table,这不是问题。在这种情况下,将使用“隐藏的”主键作为 table 的新分区键来重组 table。参见第 21 章,MySQL NDB 群集 7.5 和 NDB 群集 7.6。
也可以通过线性键对 table 进行分区。这是一个简单的示例:
CREATE TABLE tk (
col1 INT NOT NULL,
col2 CHAR(5),
col3 DATE
)
PARTITION BY LINEAR KEY (col1)
PARTITIONS 3;
使用LINEAR
对KEY
分区具有与HASH
分区相同的效果,其中分区号是使用 2 的幂数算法而不是模算术得出的。有关此算法及其含义的说明,请参见第 22.2.4.1 节“线性哈希分区”。