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] KEY
。ALGORITHM=1
使服务器使用MySQL 5.1计算行在分区中的位置时的同一个键哈希函数;ALGORITHM=2
表示服务器使用默认的键哈希函数,用于MySQL 5.5及后续版本的KEY
分区表;不指定该选项等同于使用ALGORITHM=2
。这个选项主要用于升级或降级[LINEAR] KEY
分区表之间的MySQL 5.1和后续版本,或者在MySQL 5.5及后续版本服务器上创建使用MySQL 5.1服务器的KEY
或LINEAR 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
可以用来删除一个或多个RANGE
或LIST
分区。不能与HASH
或KEY
分区一起使用;相反,使用COALESCE PARTITION
(后面在本节中介绍)。删除的分区中的所有数据将被丢弃。例如,对于之前定义的表t1
,可以删除名为p0
和p1
的分区,如下所示:ALTER TABLE t1 DROP PARTITION p0, p1;
NoteDROP PARTITION
不支持使用NDB
存储引擎的表。见第26.3.1节,“RANGE 和 LIST 分区管理”,和第25.2.7节,“NDB 集群已知限制”。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
时,允许指定分区和子分区名称。指定分区名称时,包括该分区的所有子分区。可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
条件的分区表。例如,这个语句从分区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
可以与HASH
或KEY
分区一起使用,以将分区数量减少到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 THAN
或VALUES IN
定义的某些分区的范围值列表。
Note对于没有被明确命名的分区,MySQL自动提供默认名称
p0
、p1
、p2
等。同样,对于子分区也一样。关于
ALTER TABLE ... REORGANIZE PARTITION
语句的详细信息和示例,见第26.3.1节,“RANGE 和 LIST 分区管理”. -
-
要交换一个表的分区或子分区到另一个表,使用
ALTER TABLE ... EXCHANGE PARTITION
语句—that是,将分区或子分区中的任何现有行移到非分区表中,将非分区表中的任何现有行移到分区或子分区中。一旦使用
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
会导致整个表重建和分析,并发出相应警告。(Bug #11751825,Bug #42822)为了解决这个问题,可以使用ALTER TABLE ... REBUILD PARTITION
和ALTER TABLE ... ANALYZE PARTITION
代替。ANALYZE PARTITION
、CHECK PARTITION
、OPTIMIZE PARTITION
和REPAIR PARTITION
选项不支持非分区表。 -
REMOVE PARTITIONING
可以将表的分区移除,而不会影响表或数据。这个选项可以与其他ALTER TABLE
选项结合,例如添加、删除或重命名列或索引。 -
使用
ALTER TABLE
中的ENGINE
选项可以更改表的存储引擎,而不影响分区。目标存储引擎必须提供自己的分区处理器。只有InnoDB
和NDB
存储引擎拥有native分区处理器。
ALTER TABLE
语句可以包含PARTITION BY
或REMOVE PARTITIONING
子句,除了其他 alter 指定外,但必须在最后指定。PARTITION BY
或REMOVE PARTITIONING
子句必须是最后一个指定。
ADD PARTITION
、DROP PARTITION
、COALESCE PARTITION
、REORGANIZE PARTITION
、ANALYZE PARTITION
、CHECK PARTITION
和REPAIR PARTITION
选项不能与其他 alter 指定在同一个ALTER TABLE
中,因为这些选项作用于单个分区。更多信息,请见第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节,“分区维护”。