根据键分区类似于根据哈希分区,除了哈希分区使用用户定义的表达式,而键分区使用 MySQL 服务器提供的哈希函数。NDB Cluster 使用 MD5()
进行此目的;对于使用其他存储引擎的表,服务器使用其内部哈希函数。
使用 CREATE TABLE ... PARTITION BY KEY
创建表的语法规则与使用哈希分区创建表的语法规则相似。主要区别列举如下:
-
KEY
而不是HASH
。 -
KEY
只接受零个或多个列名作为参数。用于分区键的任何列必须是表的主键的一部分,如果表有主键。例如,以下CREATE TABLE
语句在 MySQL 8.3 中是有效的: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
列,即使它不在SHOW CREATE TABLE
的输出中或在信息模式PARTITIONS
表的PARTITION_EXPRESSION
列中显示。与其他分区类型不同,用于键分区的列不限于整数或
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
是表的主键。)有关此问题的更多信息,请参阅 第 26.6 节,“分区限制和限制”。
带有索引前缀的列不支持在分区键中。这意味着
CHAR
、VARCHAR
、BINARY
和VARBINARY
列可以在分区键中使用,只要它们不使用前缀;因为BLOB
和TEXT
列在索引定义中需要指定前缀,因此无法在分区键中使用这些类型的列。在 MySQL 的早期版本中,创建、修改或升级分区表时,即使这些列不在表的分区键中,也允许使用这些列;在 MySQL 8.3 中,这种宽松行为已弃用,服务器将在使用这些列时显示适当的警告或错误信息。请参阅 列索引前缀不支持键分区,以获取更多信息和示例。Note使用
NDB
存储引擎的表隐式地按键分区,使用表的主键作为分区键(与其他 MySQL 存储引擎相同)。如果 NDB Cluster 表没有明确的主键,那么NDB
存储引擎为每个 NDB Cluster 表生成的“隐藏”主键将被用作分区键。如果您为
NDB
表定义了显式的分区方案,该表必须具有显式的主键,并且分区表达式中使用的任何列都必须是该键的一部分。然而,如果表使用了 “空” 分区表达式,即PARTITION BY KEY()
不带任何列引用,那么不需要显式主键。您可以使用 ndb_desc 实用程序(带有
-p
选项)观察这种分区。Important对于按键分区的表,您不能执行
ALTER TABLE DROP PRIMARY KEY
,因为这样做会生成错误 ERROR 1466 (HY000): 字段在分区函数的字段列表中未找到表。这不是 NDB Cluster 表的问题,该表是使用KEY
分区的;在这种情况下,表将使用 “隐藏” 主键作为表的新分区键。请参阅 第 25 章,MySQL NDB Cluster 8.3。
也可以按线性键分区表。下面是一个简单的示例:
CREATE TABLE tk (
col1 INT NOT NULL,
col2 CHAR(5),
col3 DATE
)
PARTITION BY LINEAR KEY (col1)
PARTITIONS 3;
关键字 LINEAR
对 KEY
分区的影响与对 HASH
分区的影响相同,分区号是使用二次幂算法派生,而不是模数算法。请参阅 第 26.2.4.1 节,“线性哈希分区”,以获取该算法的描述及其含义。