MySQL 8.4 参考手册  /  分区  /  分区类型

26.2 分区类型

本节讨论 MySQL 8.4 中可用的分区类型。这些类型包括这里列出的类型

  • RANGE 分区。 此类分区根据落在给定范围内的列值将行分配给分区。请参阅第 26.2.1 节“RANGE 分区”。有关此类型的扩展(RANGE COLUMNS)的信息,请参阅第 26.2.3.1 节“RANGE COLUMNS 分区”

  • LIST 分区。 与按 RANGE 分区类似,不同之处在于分区是根据与一组离散值之一匹配的列来选择的。请参阅第 26.2.2 节“LIST 分区”。有关此类型的扩展(LIST COLUMNS)的信息,请参阅第 26.2.3.2 节“LIST COLUMNS 分区”

  • HASH 分区。 使用此类分区时,将根据用户定义的表达式的返回值选择分区,该表达式对要插入到表中的行中的列值进行操作。该函数可以包含 MySQL 中有效的任何表达式,该表达式产生一个整数值。请参阅第 26.2.4 节“HASH 分区”

    此类型还有一个扩展,LINEAR HASH,请参阅第 26.2.4.1 节“LINEAR HASH 分区”

  • KEY 分区。 此类分区类似于按 HASH 分区,不同之处在于只提供一个或多个要评估的列,并且 MySQL 服务器提供其自己的哈希函数。这些列可以包含除整数值以外的值,因为 MySQL 提供的哈希函数保证无论列数据类型如何都能产生一个整数结果。此类型还有一个扩展,LINEAR KEY。请参阅第 26.2.5 节“KEY 分区”

数据库分区的一个非常常见的用途是按日期隔离数据。某些数据库系统支持显式日期分区,而 MySQL 在 8.4 中没有实现。但是,在 MySQL 中,根据 DATETIMEDATETIME 列,或者根据使用此类列的表达式来创建分区方案并不困难。

当按 KEYLINEAR KEY 分区时,可以使用 DATETIMEDATETIME 列作为分区列,而无需对列值进行任何修改。例如,此表创建语句在 MySQL 中是完全有效的

CREATE TABLE members (
    firstname VARCHAR(25) NOT NULL,
    lastname VARCHAR(25) NOT NULL,
    username VARCHAR(16) NOT NULL,
    email VARCHAR(35),
    joined DATE NOT NULL
)
PARTITION BY KEY(joined)
PARTITIONS 6;

在 MySQL 8.4 中,还可以使用 DATEDATETIME 列作为使用 RANGE COLUMNSLIST COLUMNS 分区的 partitioining 列。

其他分区类型需要一个产生整数值或 NULL 的分区表达式。如果希望通过 RANGELISTHASHLINEAR HASH 使用基于日期的分区,则只需使用对 DATETIMEDATETIME 列进行操作并返回此类值的函数,如下所示

CREATE TABLE members (
    firstname VARCHAR(25) NOT NULL,
    lastname VARCHAR(25) NOT NULL,
    username VARCHAR(16) NOT NULL,
    email VARCHAR(35),
    joined DATE NOT NULL
)
PARTITION BY RANGE( YEAR(joined) ) (
    PARTITION p0 VALUES LESS THAN (1960),
    PARTITION p1 VALUES LESS THAN (1970),
    PARTITION p2 VALUES LESS THAN (1980),
    PARTITION p3 VALUES LESS THAN (1990),
    PARTITION p4 VALUES LESS THAN MAXVALUE
);

有关使用日期进行分区的其他示例,请参阅本章的以下部分

有关更复杂的基于日期的分区示例,请参阅以下部分

MySQL 分区经过优化,可与 TO_DAYS()YEAR()TO_SECONDS() 函数一起使用。但是,您可以使用其他返回整数或 NULL 的日期和时间函数,例如 WEEKDAY()DAYOFYEAR()MONTH()。有关此类函数的更多信息,请参阅第 14.7 节“日期和时间函数”

重要的是要记住,无论使用哪种类型的分区,分区在创建时始终会自动按顺序编号,从 0 开始。将新行插入到分区表中时,将使用这些分区号来标识正确的分区。例如,如果您的表使用 4 个分区,则这些分区的编号为 0123。对于 RANGELIST 分区类型,必须确保为每个分区号定义了一个分区。对于 HASH 分区,用户提供的表达式必须计算为整数值。对于 KEY 分区,此问题由 MySQL 服务器在内部使用的哈希函数自动处理。

分区名称通常遵循 governing other MySQL 标识符的规则,例如表和数据库的标识符。但是,您应该注意,分区名称不区分大小写。例如,以下 CREATE TABLE 语句将失败,如下所示

mysql> CREATE TABLE t2 (val INT)
    -> PARTITION BY LIST(val)(
    ->     PARTITION mypart VALUES IN (1,3,5),
    ->     PARTITION MyPart VALUES IN (2,4,6)
    -> );
ERROR 1488 (HY000): Duplicate partition name mypart

发生故障是因为 MySQL 没有看到分区名称 mypartMyPart 之间的区别。

当您指定表的 partitioin 数量时,必须将其表示为一个正的、非零的整数字面量,且前面没有零,并且不能是表达式(例如 0.8E+016-2),即使它计算结果为整数值也是如此。不允许使用小数。

在以下部分中,我们不一定会提供可用于创建每种分区类型的所有可能的语法形式;有关此信息,请参阅第 15.1.20 节“CREATE TABLE 语句”