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 节“分区的限制和限制”

分区键不支持带有索引前缀的列。这意味着CHARVARCHARBINARYVARBINARY列可以在分区键中使用,只要它们不使用前缀即可。因为必须在索引定义中为BLOBTEXT列指定前缀,所以无法在分区键中使用这两种类型的列。在 MySQL 5.7 中,创建,更改或升级分区 table 时允许使用带有前缀的列,即使它们不包含在 table 的分区键中也是如此。这是 MySQL 5.7 中的一个已知问题,而 MySQL 8.0 中已解决此问题,该行为已被弃用,并且在这些情况下尝试使用此类列时,服务器会显示适当的警告或错误。有关更多信息和示例,请参见键分区不支持列索引前缀

Note

使用NDB存储引擎的 table 被KEY隐式分区,使用 table 的主键作为分区键(与其他 MySQL 存储引擎一样)。如果 NDB 群集 table 没有显式主键,则NDB存储引擎为每个 NDB 群集 table 生成的“隐藏”主键用作分区键。

如果为NDBtable 定义显式分区方案,则该 table 必须具有显式主键,并且分区 table 达式中使用的任何列都必须是该键的一部分。但是,如果 table 使用“空”分区 table 达式(即PARTITION BY KEY(),没有列引用),则不需要显式主键。

您可以使用ndb_descUtil(带有-p选项)观察该分区。

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;

使用LINEARKEY分区具有与HASH分区相同的效果,其中分区号是使用 2 的幂数算法而不是模算术得出的。有关此算法及其含义的说明,请参见第 22.2.4.1 节“线性哈希分区”