针对ALTER TABLE
的与分区相关的子句可用于对分区表进行重新分区,以添加、删除、丢弃、导入、合并和拆分分区,以及执行分区维护操作。
只需在分区表上使用
ALTER TABLE
和partition_options
子句即可根据partition_options
定义的分区方案对表进行重新分区。此子句始终以PARTITION BY
开头,并遵循与CREATE TABLE
的partition_options
子句相同的语法和其他规则(有关更详细的信息,请参阅 第 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 支持使用
[SUB]PARTITION BY [LINEAR] KEY
的ALGORITHM
选项。ALGORITHM=1
会使服务器在计算行在分区中的放置位置时使用与 MySQL 5.1 相同的键哈希函数;ALGORITHM=2
意味着服务器使用在 MySQL 5.5 及更高版本中默认实现和使用的键哈希函数。(使用在 MySQL 5.5 及更高版本中使用的键哈希函数创建的分区表不能由 MySQL 5.1 服务器使用。)不指定该选项与使用ALGORITHM=2
的效果相同。此选项主要用于在 MySQL 5.1 和更高版本的 MySQL 版本之间升级或降级[LINEAR] KEY
分区表时,或在 MySQL 5.5 或更高版本的服务器上创建通过KEY
或LINEAR KEY
分区的表,这些表可以在 MySQL 5.1 服务器上使用。使用
ALTER TABLE ... PARTITION BY
语句生成的结果表必须遵循与使用CREATE TABLE ... PARTITION BY
创建的表相同的规则。这包括管理表可能具有的任何唯一键(包括任何主键)与分区表达式中使用的列或列之间的关系的规则,如第 26.6.1 节,“分区键、主键和唯一键” 中所述。指定分区数量的CREATE TABLE ... PARTITION BY
规则也适用于ALTER TABLE ... PARTITION BY
。用于
ALTER TABLE ADD PARTITION
的partition_definition
子句支持与用于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) );
您可以向此表添加一个名为
p3
的新分区,用于存储小于2002
的值,方法如下ALTER TABLE t1 ADD PARTITION (PARTITION p3 VALUES LESS THAN (2002));
DROP PARTITION
可用于删除一个或多个RANGE
或LIST
分区。此语句不能与HASH
或KEY
分区一起使用;相反,请使用COALESCE PARTITION
(见本节后面的内容)。存储在partition_names
列表中命名的已删除分区中的所有数据都将被丢弃。例如,给定之前定义的表t1
,您可以按如下所示删除名为p0
和p1
的分区ALTER TABLE t1 DROP PARTITION p0, p1;
注意DROP PARTITION
不适用于使用NDB
存储引擎的表。请参见第 26.3.1 节,“RANGE 和 LIST 分区的管理” 和第 25.2.7 节,“NDB Cluster 的已知限制”。ADD PARTITION
和DROP PARTITION
目前不支持IF [NOT] EXISTS
。DISCARD PARTITION ... TABLESPACE
和IMPORT PARTITION ... TABLESPACE
选项将 可移植表空间 功能扩展到各个InnoDB
表分区。每个InnoDB
表分区都有自己的表空间文件(.ibd
文件)。可移植表空间 功能可以轻松地将表空间从一个正在运行的 MySQL 服务器实例复制到另一个正在运行的实例,或在同一个实例上执行恢复操作。这两个选项都采用一个或多个分区名称的逗号分隔列表。例如ALTER TABLE t1 DISCARD PARTITION p2, p3 TABLESPACE;
ALTER TABLE t1 IMPORT PARTITION p2, p3 TABLESPACE;
在子分区表上运行
DISCARD PARTITION ... TABLESPACE
和IMPORT PARTITION ... TABLESPACE
时,分区和子分区名称都是允许的。当指定分区名称时,将包含该分区的所有子分区。可移植表空间 功能还支持复制或恢复分区
InnoDB
表。有关详细信息,请参见第 17.6.1.3 节,“导入 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;
截断多个分区时,分区不必连续:这可以极大地简化分区表的删除操作,否则如果使用
DELETE
语句,则需要非常复杂的WHERE
条件。例如,以下语句会从分区p1
和p3
中删除所有行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
可用于通过number
减少通过HASH
或KEY
分区的表的分区数量。假设您已创建表t2
,如下所示CREATE TABLE t2 ( name VARCHAR (30), started DATE ) PARTITION BY HASH( YEAR(started) ) PARTITIONS 6;
要将
t2
使用的分区数量从 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 THAN
定义的子集分区范围或更改使用VALUES IN
定义的子集分区的值列表。
注意对于没有显式命名的分区,MySQL 会自动提供默认名称
p0
、p1
、p2
等。子分区也是如此。有关
ALTER TABLE ... REORGANIZE PARTITION
语句的更详细的信息和示例,请参见第 26.3.1 节,“RANGE 和 LIST 分区的管理”。要将表分区或子分区与表交换,请使用
ALTER TABLE ... EXCHANGE PARTITION
语句,即,将分区或子分区中的所有现有行移动到非分区表,并将非分区表中的所有现有行移动到表分区或子分区。一旦使用
ALGORITHM=INSTANT
向分区表添加了一列或多列,就无法再将分区与该表交换。有关使用方法和示例,请参见第 26.3.3 节,“将分区和子分区与表交换”。
几个选项提供类似于通过
CHECK TABLE
和REPAIR TABLE
(也支持分区表;有关详细信息,请参见第 15.7.3 节,“表维护语句”)等语句为非分区表实现的功能的分区维护和修复功能。这些选项包括ANALYZE PARTITION
、CHECK PARTITION
、OPTIMIZE PARTITION
、REBUILD PARTITION
和REPAIR PARTITION
。每个选项都采用一个partition_names
子句,该子句由一个或多个分区名称(以逗号分隔)组成。这些分区必须已存在于目标表中。您也可以使用ALL
关键字代替partition_names
,在这种情况下,该语句会对所有表分区起作用。有关详细信息和示例,请参见第 26.3.4 节,“分区的维护”。InnoDB
目前不支持按分区优化;ALTER TABLE ... OPTIMIZE PARTITION
会导致整个表重建和分析,并会发出相应的警告。(错误 #11751825,错误 #42822)要解决此问题,请改用ALTER TABLE ... REBUILD PARTITION
和ALTER TABLE ... ANALYZE PARTITION
。对于未分区的表,不支持
ANALYZE PARTITION
、CHECK PARTITION
、OPTIMIZE PARTITION
和REPAIR PARTITION
选项。REMOVE PARTITIONING
使您能够删除表的划分,而不会影响表或其数据。此选项可以与其他ALTER TABLE
选项结合使用,例如用于添加、删除或重命名列或索引的选项。将
ENGINE
选项与ALTER TABLE
一起使用会更改表使用的存储引擎,而不会影响划分。目标存储引擎必须提供自己的划分处理程序。只有InnoDB
和NDB
存储引擎具有本机划分处理程序。
一个 ALTER TABLE
语句可以包含 PARTITION BY
或 REMOVE PARTITIONING
子句,以及其他更改规范,但 PARTITION BY
或 REMOVE PARTITIONING
子句必须在所有其他规范之后最后指定。
在单个 ALTER TABLE
语句中,ADD PARTITION
、DROP PARTITION
、COALESCE PARTITION
、REORGANIZE PARTITION
、ANALYZE PARTITION
、CHECK PARTITION
和 REPAIR PARTITION
选项不能与其他 ALTER 规范组合使用,因为这些选项仅作用于单个分区。有关更多信息,请参见 第 15.1.9.1 节,“ALTER TABLE 分区操作”。
在给定的 ALTER TABLE
语句中,只能使用以下选项中的单个实例:PARTITION BY
、ADD PARTITION
、DROP PARTITION
、TRUNCATE PARTITION
、EXCHANGE PARTITION
、REORGANIZE PARTITION
或 COALESCE PARTITION
、ANALYZE PARTITION
、CHECK PARTITION
、OPTIMIZE PARTITION
、REBUILD PARTITION
、REMOVE PARTITIONING
。
例如,以下两个语句无效
ALTER TABLE t1 ANALYZE PARTITION p1, ANALYZE PARTITION p2;
ALTER TABLE t1 ANALYZE PARTITION p1, CHECK PARTITION p2;
在第一种情况下,您可以使用单个语句和单个 ANALYZE PARTITION
选项(其中列出了要分析的两个分区)来并发分析表 t1
的分区 p1
和 p2
,如下所示
ALTER TABLE t1 ANALYZE PARTITION p1, p2;
在第二种情况下,无法对同一表的不同分区并发执行 ANALYZE
和 CHECK
操作。相反,您必须发出两个单独的语句,如下所示
ALTER TABLE t1 ANALYZE PARTITION p1;
ALTER TABLE t1 CHECK PARTITION p2;
REBUILD
操作当前不支持子分区。REBUILD
关键字在子分区中明确禁止,如果使用,会导致 ALTER TABLE
失败并出现错误。
当要检查或修复的分区包含任何重复键错误时,CHECK PARTITION
和 REPAIR PARTITION
操作将失败。
有关这些语句的更多信息,请参见 第 26.3.4 节,“分区维护”。