Documentation Home
MySQL 8.4 Reference Manual
Related Documentation Download this Manual
PDF (US Ltr) - 39.8Mb
PDF (A4) - 39.9Mb
Man Pages (TGZ) - 257.9Kb
Man Pages (Zip) - 364.9Kb
Info (Gzip) - 4.0Mb
Info (Zip) - 4.0Mb


MySQL 8.4 Reference Manual  /  ...  /  ALTER TABLE Partition Operations

15.1.9.1 ALTER TABLE 分区操作

ALTER TABLE 中的分区相关子句可以用来对分区表进行重分区、添加、删除、丢弃、导入、合并和拆分分区,执行分区维护操作。

  • 使用ALTER TABLE在分区表上简单地使用partition_options子句,根据partition_options定义的分区方案重分区该表。这个子句总是以PARTITION BY开始,并遵循CREATE TABLE(详细信息请见第15.1.20节,“CREATE TABLE 语句”)的同一语法和规则,可以用来对未分区的表进行分区。例如,考虑一个非分区的表,如下所示:

    CREATE TABLE t1 (
        id INT,
        year_col INT
    );

    这个表可以使用HASH方式,以id列作为分区键,通过以下语句将其分成8个分区:

    ALTER TABLE t1
        PARTITION BY HASH(id)
        PARTITIONS 8;

    MySQL支持ALGORITHM选项与[SUB]PARTITION BY [LINEAR] KEYALGORITHM=1使服务器使用MySQL 5.1计算行在分区中的位置时的同一个键哈希函数;ALGORITHM=2表示服务器使用默认的键哈希函数,用于MySQL 5.5及后续版本的KEY分区表;不指定该选项等同于使用ALGORITHM=2。这个选项主要用于升级或降级[LINEAR] KEY分区表之间的MySQL 5.1和后续版本,或者在MySQL 5.5及后续版本服务器上创建使用MySQL 5.1服务器的KEYLINEAR KEY分区表。

    使用ALTER TABLE ... PARTITION BY语句生成的表必须遵守使用CREATE TABLE ... PARTITION BY语句生成的表相同的规则,包括讨论在第26.6.1节,“分区键、主键和唯一键”中的任何唯一键(包括可能存在的主键)与分区表达式中使用的列或列之间的关系,以及指定分区数的规则也适用于ALTER TABLE ... PARTITION BY

    partition_definition子句在ALTER TABLE ADD PARTITION语句中支持与同名子句在CREATE TABLE语句中的选项相同。请参阅第15.1.20节,“CREATE TABLE 语句”,了解语法和描述。

    CREATE TABLE t1 (
        id INT,
        year_col INT
    )
    PARTITION BY RANGE (year_col) (
        PARTITION p0 VALUES LESS THAN (1991),
        PARTITION p1 VALUES LESS THAN (1995),
        PARTITION p2 VALUES LESS THAN (1999)
    );

    假设您已经创建了一个分区表,如下所示:

    ALTER TABLE t1 ADD PARTITION (PARTITION p3 VALUES LESS THAN (2002));

    DROP PARTITION可以用来删除一个或多个RANGELIST分区。不能与HASHKEY分区一起使用;相反,使用COALESCE PARTITION(后面在本节中介绍)。删除的分区中的所有数据将被丢弃。例如,对于之前定义的表t1,可以删除名为p0p1的分区,如下所示:

    ALTER TABLE t1 DROP PARTITION p0, p1;
    Note

    DROP PARTITION 不支持使用NDB存储引擎的表。见第26.3.1节,“RANGE 和 LIST 分区管理”,和第25.2.7节,“NDB 集群已知限制”

    ADD PARTITIONDROP PARTITION 目前不支持IF [NOT] EXISTS子句。

    DISCARD PARTITION ... TABLESPACEIMPORT PARTITION ... TABLESPACE 选项扩展了可传输表空间特性到单个InnoDB 表分区。每个InnoDB 表分区都有自己的表空间文件(.ibd 文件)。可传输表空间特性使得可以轻松地将运行中的 MySQL 服务器实例的表空间复制到另一个实例,或者在同一实例进行恢复。两个选项都接受一个或多个分区名称的逗号分隔列表。例如:

    ALTER TABLE t1 DISCARD PARTITION p2, p3 TABLESPACE;
    ALTER TABLE t1 IMPORT PARTITION p2, p3 TABLESPACE;

    在对子分区表执行DISCARD PARTITION ... TABLESPACEIMPORT PARTITION ... TABLESPACE时,允许指定分区和子分区名称。指定分区名称时,包括该分区的所有子分区。

    可transportable 表空间特性还支持复制或恢复分区的InnoDB表。更多信息,请参见第17.6.1.3节,“Importing InnoDB 表”.

    支持重命名分区表。可以使用ALTER TABLE ... REORGANIZE PARTITION间接地重命名单个分区;然而,这个操作会复制分区的数据。

    要删除指定分区中的行,使用TRUNCATE PARTITION选项。这个选项接受一个或多个逗号分隔的分区名称。考虑创建了以下语句的表t1

    CREATE TABLE t1 (
        id INT,
        year_col INT
    )
    PARTITION BY RANGE (year_col) (
        PARTITION p0 VALUES LESS THAN (1991),
        PARTITION p1 VALUES LESS THAN (1995),
        PARTITION p2 VALUES LESS THAN (1999),
        PARTITION p3 VALUES LESS THAN (2003),
        PARTITION p4 VALUES LESS THAN (2007)
    );

    要删除所有行从分区p0,使用以下语句:

    ALTER TABLE t1 TRUNCATE PARTITION p0;

    显示的语句与以下DELETE语句相同:

    DELETE FROM t1 WHERE year_col < 1991;

    当truncate多个分区时,分区不需要连续:这可以简化删除操作,对于否则需要使用复杂WHERE条件的分区表。例如,这个语句从分区p1p3中删除所有行:

    ALTER TABLE t1 TRUNCATE PARTITION p1, p3;

    等效的DELETE语句如下:

    DELETE FROM t1 WHERE
        (year_col >= 1991 AND year_col < 1995)
        OR
        (year_col >= 2003 AND year_col < 2007);

    如果使用ALL关键字代替分区名列表,语句将作用于表的所有分区。

    TRUNCATE PARTITION仅删除行,不会修改表或其任何分区的定义。

    验证已删除行,可以查看INFORMATION_SCHEMA.PARTITIONS表,使用以下查询:

    SELECT PARTITION_NAME, TABLE_ROWS
        FROM INFORMATION_SCHEMA.PARTITIONS
        WHERE TABLE_NAME = 't1';

    COALESCE PARTITION可以与HASHKEY分区一起使用,以将分区数量减少到number。假设你创建了表t2如下:

    CREATE TABLE t2 (
        name VARCHAR (30),
        started DATE
    )
    PARTITION BY HASH( YEAR(started) )
    PARTITIONS 6;

    从6个分区减少到4个分区,可以使用以下语句:

    ALTER TABLE t2 COALESCE PARTITION 2;

    最后number个分区中的数据被合并到剩余的分区中。在这个例子中,分区4和5被合并到前4个分区(编号为0、1、2和3)。

    要更改一个分区表中的一些但不是所有的分区,可以使用REORGANIZE PARTITION语句。这条语句可以以多种方式使用:

    • 将多个分区合并到一个分区中。通过在partition_names列表中指定多个分区,并提供单个的partition_definition定义。

    • 将一个已有的分区拆分成多个分区。通过在partition_names中指定单个分区,并提供多个partition_definitions定义。

    • 更改使用VALUES LESS THANVALUES IN定义的某些分区的范围值列表。

    Note

    对于没有被明确命名的分区,MySQL自动提供默认名称p0p1p2等。同样,对于子分区也一样。

    关于ALTER TABLE ... REORGANIZE PARTITION语句的详细信息和示例,见第26.3.1节,“RANGE 和 LIST 分区管理”.

  • 要交换一个表的分区或子分区到另一个表,使用ALTER TABLE ... EXCHANGE PARTITION语句—that是,将分区或子分区中的任何现有行移到非分区表中,将非分区表中的任何现有行移到分区或子分区中。

    一旦使用ALGORITHM=INSTANT添加了一个或多个列到分区表,那么对该表进行交换分区就不再可能。

    使用信息和示例,请参见第26.3.3节,“与表交换分区和子分区”

  • 有几个选项提供了类似于非分区表的语句CHECK TABLEREPAIR TABLE(也支持分区表;更多信息,请参见第15.7.3节,“表维护语句”)的分区维护和修复功能。这些选项包括ANALYZE PARTITIONCHECK PARTITIONOPTIMIZE PARTITIONREBUILD PARTITIONREPAIR PARTITION。每个选项都需要一个partition_names子句,包括一个或多个分区名,使用逗号分隔。这些分区必须已经存在于目标表中。你也可以将ALL关键字用作partition_names,那么语句就对所有表分区进行操作。更多信息和示例,请参见第26.3.4节,“分区维护”

    InnoDB当前不支持每个分区的优化;ALTER TABLE ... OPTIMIZE PARTITION会导致整个表重建和分析,并发出相应警告。(Bug #11751825,Bug #42822)为了解决这个问题,可以使用ALTER TABLE ... REBUILD PARTITIONALTER TABLE ... ANALYZE PARTITION代替。

    ANALYZE PARTITIONCHECK PARTITIONOPTIMIZE PARTITIONREPAIR PARTITION选项不支持非分区表。

  • REMOVE PARTITIONING可以将表的分区移除,而不会影响表或数据。这个选项可以与其他ALTER TABLE选项结合,例如添加、删除或重命名列或索引。

  • 使用ALTER TABLE中的ENGINE选项可以更改表的存储引擎,而不影响分区。目标存储引擎必须提供自己的分区处理器。只有InnoDBNDB存储引擎拥有native分区处理器。

ALTER TABLE 语句可以包含PARTITION BYREMOVE PARTITIONING子句,除了其他 alter 指定外,但必须在最后指定。PARTITION BYREMOVE PARTITIONING子句必须是最后一个指定。

ADD PARTITIONDROP PARTITIONCOALESCE PARTITIONREORGANIZE PARTITIONANALYZE PARTITIONCHECK PARTITIONREPAIR PARTITION选项不能与其他 alter 指定在同一个ALTER TABLE中,因为这些选项作用于单个分区。更多信息,请见第15.1.9.1节,“ALTER TABLE 分区操作”

在给定的ALTER TABLE语句中,只能使用一个PARTITION BYADD PARTITIONDROP PARTITIONTRUNCATE PARTITIONEXCHANGE PARTITIONREORGANIZE PARTITIONCOALESCE PARTITIONANALYZE PARTITIONCHECK PARTITIONOPTIMIZE PARTITIONREBUILD PARTITIONREMOVE PARTITIONING选项。

例如,以下两个语句都是无效的:

ALTER TABLE t1 ANALYZE PARTITION p1, ANALYZE PARTITION p2;

ALTER TABLE t1 ANALYZE PARTITION p1, CHECK PARTITION p2;

在第一个情况下,您可以使用单个语句,通过单个ANALYZE PARTITION选项来并发分析表t1中的分区p1p2,如下所示:

ALTER TABLE t1 ANALYZE PARTITION p1, p2;

在第二个情况下,不可能对同一张表的不同分区同时执行ANALYZECHECK操作。相反,您必须发出两个单独语句,如下所示:

ALTER TABLE t1 ANALYZE PARTITION p1;
ALTER TABLE t1 CHECK PARTITION p2;

REBUILD操作当前不支持子分区。使用REBUILD关键字在子分区上是明确禁止的,并且如果这样使用,会导致ALTER TABLE语句失败。

CHECK PARTITION REPAIR PARTITION操作在要检查或修复的分区中存在重复键错误时将失败。

关于这些语句的更多信息,请参见第26.3.4节,“分区维护”