
# 修改分区表
本章节介绍修改分区表的语法。
表1语法一览表 
| 语法                                                                                                     | 含义                                                     |
|:---|:---|
| [ADD PARTITION]        | 将分区和子分区添加到现有分区表。                                       |
| [DROP PARTITION]       | 删除分区和子分区以及存储的数据。                                       |
| [TRUNCATE PARTITION]  | 从指定的分区或子分区中删除所有数据，并保留完整的子分区结构。                         |
| [COALESCE PARTITION]  | 减少基于HASH和KEY分区的分区数和对应分区的所有子分区，并将数据合并到其他分区和子分区中。        |
| [REORGANIZE PARTITION] | 对LIST或RANGE分区表的分区进行结构重组（如合并、拆分或修改分区），同时自动重新分布数据且不丢失数据。 |
| [EXCHANGE PARTITION] | 将一个分区或子分区与单表进行交换，可以将一个与分区表的表结构相同的单表交换为分区表中的一个分区或子分区。   |
| [ANALYZE PARTITION]    | 更新分区或子分区的统计信息。                                         |
| [CHECK PARTITION]    | 检查分区或子分区，并显示分区或子分区中的数据或者索引是否已损坏。                       |
| [OPTIMIZE PARTITION]    | 优化分区或子分区、回收未使用的空间和整理分区数据文件的碎片。                         |
| [REBUILD PARTITION]   | 重建分区。                                                  |
| [REPAIR PARTITION]   | 修复损坏的分区或子分区。                                           |
| [REMOVE PARTITION]   | 删除分区和子分区表的分区结构。                                        |
   
 #### ADD PARTITION
**描述**：
将分区和子分区添加到现有分区表。
**语法**：
ALTER TABLE...ADD PARTITION命令用于添加分区和子分区到现有的分区表中，且这个分区表必须已经进行了子分区的划分。
新的分区和子分区必须与现有分区和子分区的类型相同。新分区规则必须引用和定义现有分区的分区规则中指定的相同列。
```
ALTER TABLE table_name ADD PARTITION partition_definition;
```
partition_definition为：
```
{list_partition | range_partition | hash_partition | key_partition}
```
其中list_partition为：
```
PARTITION [partition_name] VALUES IN (value[, value]...) [TABLESPACE tablespace_name]、 (subpartition, ...)
```
range_partition为：
```
PARTITION partition_name VALUES LESS THAN (value[, value]...) [TABLESPACE tablespace_name] [(subpartition, ...)]
```
hash_partition\|key_partition为：
```
PARTITION partition_name [TABLESPACE tablespace_name] (subpartition, ...)
```
其中subpartition为：
```
{list_subpartition | range_subpartition ｜ hash_partition | key_partition}
```
list_subpartition 为：
```
SUBPARTITION [subpartition_name] VALUES IN (value[, value]...) [TABLESPACE tablespace_name]
```
range_subpartition为：
```
SUBPARTITION [subpartition_name ] VALUES LESS THAN (value[, value]...) [TABLESPACE tablespace_name]
```
hash_partition\|key_subpartition为：
```
SUBPARTITION [subpartition_name ] [TABLESPACE tablespace_name]
```
表2参数介绍 
| 参数                    | 参数说明                                                                                                                                                |
|:---|:---|
| table_name            | 添加分区的表名称。                                                                                                                                           |
| partition_name        | 要创建的分区名称。分区名称在所有分区和子分区中必须是唯一的，且必须遵循给对象标识符命名的惯例。                                                                                                     |
| subpartition_name     | 要创建的子分区名称。子分区名称在所有分区和子分区中必须是唯一的，且必须遵循给对象标识符命名的惯例。                                                                                                   |
| (value\[, value\]...) | 使用value来指定一个引用的文本值（或以逗号分隔的文本值列表）将表项目划分为不同的分区。每个分区规则必须至少指定一个值，但在规则中对于指定的值的数量没有上限要求。value可能为null、default（如果指定了一个list分区的话）或maxvalue（如果指定了一个range分区的话）。 |
| tablespace_name       | 分区或子分区所属的表空间名称。                                                                                                                                     |
   
**示例**：
RANGE分区必须以升序的方式指定。不能将新分区添加在RANGE分区表中现有的分区之前。
1. 假设数据库中存在sales_order分区表，建表语句如下：
   ```
   CREATE TABLE sales_order (
     region_id INT, 
     product_id INT, 
     city varchar(20), 
     order_date DATE, 
     quantity INT
   ) PARTITION BY RANGE(region_id)
   SUBPARTITION BY RANGE(product_id) (
     PARTITION r0 VALUES LESS THAN (1000) (
         SUBPARTITION s0 VALUES LESS THAN(100),
         SUBPARTITION s1 VALUES LESS THAN(200), 
         SUBPARTITION s2 VALUES LESS THAN(300), 
         SUBPARTITION s3 VALUES LESS THAN(MAXVALUE)
       )
   );
   ```
   
2. 使用ALTER TABLE...ADD PARTITION命令添加分区和子分区到sales_order分区表。
   ```
   ALTER TABLE sales_order ADD PARTITION (
     PARTITION r1 VALUES less than (3000)
     (
       SUBPARTITION s0 VALUES LESS THAN(100),
       SUBPARTITION s1 VALUES LESS THAN(200),
       SUBPARTITION s2 VALUES LESS THAN(300),
       SUBPARTITION s3 VALUES LESS THAN(MAXVALUE)
     )
   );
   ```
   
 
 #### DROP PARTITION
**描述：**删除分区和子分区以及存储的数据。
**语法：**
```
ALTER TABLE table_name DROP PARTITION partition_names;
```
说明：该命令不可以单独删除子分区，也不可以删除HASH或者KEY分区
表3参数说明 
| **参数**          | **参数说明**               |
|:---|:---|
| table_name      | 分区表的名称（可以采用模式限定的方式引用）。 |
| partition_names | 要删除的分区名称。              |
   
**示例：**
删除表sales_order的分区s1：
```
ALTER TABLE sales_order DROP PARTITION s1;
```
 #### TRUNCATE PARTITION
**描述**：从指定的分区或子分区中删除所有数据，并保留完整的子分区结构。
**语法**：
```
ALTER TABLE table_name
   TRUNCATE PARTITION partition_name [,partition_name] ...
```
说明：在包含有子分区的表上执行该命令时，指定分区名称后，该分区的子分区将包含在此操作中。
其中，partition_name为：
```
{partition_name | subpartition_name}
```
表4参数说明 
| **参数**            | **参数说明**               |
|:---|:---|
| table_name        | 分区表的名称（可以采用模式限定的方式引用）。 |
| partition_name    | 要删除的分区名称。              |
| subpartition_name | 要删除的子分区名称。             |
   
**示例**：
- 删除part_range_list 表的分区r1分区的数据。
  ```
  ALTER TABLE part_range_list TRUNCATE PARTITION r1;
  ```
  
- 删除part_range_list 表的r1分区的子分区s0的数据。
  ```
  ALTER TABLE part_range_list TRUNCATE PARTITION r1_s0;
  ```
  
 
 #### COALESCE PARTITION
**描述**：减少基于HASH和KEY分区的分区数和对应分区的所有子分区，并将数据合并到其他分区和子分区中。
**语法**：
```
ALTER TABLE table_name COALESCE PARTITION num;
```
表5参数说明 
| **参数**     | **说明**                 |
|:---|:---|
| table_name | 分区表的名称（可以采用模式限定的方式引用）。 |
| num        | 减少的分区数，需要小于表分区总数。      |
   
**示例**：
- 减少part_hash_hash表中的2个分区数：
  ```
  ALTER TABLE part_hash_hash COALESCE PARTITION 2;
  ```
  
- 减少part_key_key表中的2个分区数：
  ```
  ALTER TABLE part_key_key COALESCE PARTITION 2;
  ```
  
 
 #### REORGANIZE PARTITION
**描述**：对LIST或RANGE分区表的分区进行结构重组（如合并、拆分或修改分区），同时自动重新分布数据且不丢失数据。
**语法：**
```
ALTER TABLE table_name
    REORGANIZE PARTITION partition_names INTO (partition_definitions)
partition_definitions: {list_partition | range_partition}
subpartition_definition: {list_subpartition | range_subpartition ｜ hash_subpartition | key_subpartition}
```
表6参数说明 
| **参数**                | **说明**                                                                                                                                                                                                         |
|:---|:---|
| table_name            | 表名                                                                                                                                                                                                             |
| partition_names       | 需要合并或拆分的现有分区名列表，以英文逗号分隔。                                                                                                                                                                                       |
| partition_definitions | 新分区定义列表，以英文逗号分隔。                                                                                                                                                                                               |
| partition_name        | 需要创建的分区名称。 说明 分区名称在所有分区和子分区中必须是唯一的，且必须遵循给对象标识符命名的惯例。      |
| subpartition_name     | 需要创建的子分区名称。 说明 子分区名称在所有分区和子分区中必须是唯一的，且必须遵循给对象标识符命名的惯例。 |
   
**示例**：
1. 数据准备
   ```
   CREATE TABLE sales_data (
       order_id INT AUTO_INCREMENT,    
       order_date DATE NOT NULL,     
       amount DECIMAL(10,2),
       customer_id INT,
       product_id INT,
       quantity INT,
       status VARCHAR(20),
       PRIMARY KEY (order_id, order_date)
   ) 
   PARTITION BY RANGE (TO_DAYS(order_date))
   SUBPARTITION BY KEY(order_id)
   SUBPARTITIONS 4 (
       PARTITION part_before_2022 VALUES LESS THAN (TO_DAYS('2022-01-01')),
       PARTITION part_2022      VALUES LESS THAN (TO_DAYS('2023-01-01')),
       PARTITION part_2023      VALUES LESS THAN (TO_DAYS('2024-01-01')),
       PARTITION part_future    VALUES LESS THAN MAXVALUE
   );
   INSERT INTO sales_data (order_date, amount, customer_id, product_id, quantity, status) VALUES
   ('2020-08-10', 150.00, 101, 2001, 2, 'completed'),
   ('2021-11-05', 250.00, 102, 2002, 1, 'pending'),
   ('2022-07-19', 350.00, 103, 2003, 5, 'shipped'),
   ('2023-04-02', 450.00, 104, 2004, 3, 'completed');
   ```
   
2. 拆分分区 将part_2023拆分为两个分区。
   ```
   ALTER TABLE sales_data 
   REORGANIZE PARTITION part_2023 INTO (
       PARTITION part_2023_h1 VALUES LESS THAN (TO_DAYS('2023-07-01')),
       PARTITION part_2023_h2 VALUES LESS THAN (TO_DAYS('2024-01-01'))
   );
   ```
   
3. 合并分区 将part_2022和part_2023合并为一个part_2022_2023分区。
   ```
   ALTER TABLE sales_data 
   REORGANIZE PARTITION part_2022, part_2023 INTO (
       PARTITION part_2022_2023 VALUES LESS THAN (TO_DAYS('2024-01-01'))
   );
   ```
   
4. 修改分区 将所有分区的定义做重新修改，重新定义数据范围。
   ```
   ALTER TABLE sales_data 
   REORGANIZE PARTITION part_before_2022, part_2022, part_2023, part_future INTO (
       PARTITION p_2020_2021 VALUES LESS THAN (TO_DAYS('2022-01-01')),
       PARTITION p_2022      VALUES LESS THAN (TO_DAYS('2023-01-01')),
       PARTITION p_2023      VALUES LESS THAN (TO_DAYS('2024-01-01')),
       PARTITION p_2024      VALUES LESS THAN (TO_DAYS('2025-01-01')),
       PARTITION p_future    VALUES LESS THAN MAXVALUE
   );
   ```
   
 
 #### EXCHANGE PARTITION
**描述**：将一个分区或子分区与单表进行交换，可以将一个与分区表的表结构相同的单表交换为分区表中的一个分区或子分区。
**说明：**
- ALTER TABLE ... EXCHANGE PARTITION 操作执行后，系统将完成以下数据交换：
  1. 原位于目标分区（target_partition）中的数据将迁移至源表（source_table）。
  
  2. 原位于源表（source_table）中的数据将迁移至目标分区（target_partition）。
   
- 执行EXCHANGE PARTITION操作时，需要确保source_table的结构与target_table的结构一致，即两张表必须有相同的列、数据类型、引擎、表属性以及索引。
**语法**：
```
ALTER TABLE target_table 
EXCHANGE PARTITION target_partition 
WITH TABLE source_table 
[{WITH | WITHOUT} VALIDATION];
```
表7参数说明 
| **参数**             | **说明**                                               |
|:---|:---|
| target_table       | 用于交换的目标表名称。                                          |
| target_partition   | 用于交换的目标分区名称。                                         |
| source_table       | 用于交换的源表名称。                                           |
| WITHOUT VALIDATION | 不执行数据合规性校验（跳过分区规则验证），仅修改表元数据指针实现数据交换，需要用户保证数据符合分区规则。 |
   
**示例**
分区表sales_data的p2022分区与单表sales_data_temp进行交换：
```
ALTER TABLE sales_data 
    EXCHANGE PARTITION p2022 
    WITH TABLE sales_data_temp;
```
 #### ANALYZE PARTITION
**描述**：更新分区或子分区的统计信息。
**语法**：
```
ALTER TABLE table_name ANALYZE PARTITION {partition_names | ALL}
```
其中，partition_names为：
```
{partition_name | subpartition_name}
```
表8参数说明 
| **参数**            | **参数说明**               |
|:---|:---|
| table_name        | 分区表的名称（可以采用模式限定的方式引用）。 |
| partition_name    | 分区名称。                  |
| subpartition_name | 子分区名称。                 |
   
**示例**：
- 分析sales_data表的分区part_2022。
  ```
  ALTER TABLE sales_data ANALYZE PARTITION part_2022;
  ```
  
- 分析sales_data表的子分区part_2022_sp1。
  ```
  ALTER TABLE sales_data ANALYZE PARTITION part_2022_sp1;
  ```
  
 
 #### CHECK PARTITION
**描述**：检查分区或子分区，并显示分区或子分区中的数据或者索引是否已损坏。
**语法**：
```
ALTER TABLE table_name CHECK PARTITION {partition_names | ALL}
```
其中，partition_names为：
```
{partition_name | subpartition_name}
```
表9参数说明 
| **参数**            | **参数说明**               |
|:---|:---|
| table_name        | 分区表的名称（可以采用模式限定的方式引用）。 |
| partition_name    | 分区名称。                  |
| subpartition_name | 子分区名称。                 |
   
**示例**：
- 检查sales_data表的分区part_2022。
  ```
  ALTER TABLE sales_data CHECK PARTITION part_2022;
  ```
  
- 检查sales_data表的子分区part_2022_sp1。
  ```
  ALTER TABLE sales_data CHECK PARTITION part_2022_sp1;
  ```
  
 
 #### OPTIMIZE PARTITION
**描述**：
如果从分区或子分区中删除了大量的行，或者对一个带有可变长度的行（即存在VARCHAR、BLOB或TEXT类型的列）进行修改，可以使用**ALTER TABLE ... OPTIMIZE PARTITION**来优化分区或子分区、回收未使用的空间和整理分区数据文件的碎片。
**语法：**
```
ALTER TABLE table_name OPTIMIZE PARTITION {partition_names | ALL}
```
其中，partition_names为：
```
{partition_name | subpartition_name}
```
表10参数说明 
| **参数**            | **参数说明**               |
|:---|:---|
| table_name        | 分区表的名称（可以采用模式限定的方式引用）。 |
| partition_name    | 分区名称。                  |
| subpartition_name | 子分区名称。                 |
   
**示例**：
- 优化sales_data表的分区part_2022。
  ```
  ALTER TABLE sales_data OPTIMIZE PARTITION part_2022;
  ```
  

- 优化sales_data表的子分区part_2022_sp1。
  ```
  ALTER TABLE sales_data OPTIMIZE PARTITION part_2022_sp1;
  ```
  
 
 #### REBUILD PARTITION
**描述**：重建分区。
**语法**：
```
ALTER TABLE table_name REBUILD PARTITION {partition_names | ALL}
```
表11参数说明 
| **参数**         | **参数说明**               |
|:---|:---|
| table_name     | 分区表的名称（可以采用模式限定的方式引用）。 |
| partition_name | 分区名称。                  |
   
**示例**：
重建sales_data表的分区part_2022。
```
ALTER TABLE part_range_list REBUILD PARTITION part_2022;
```
 #### REPAIR PARTITION
**描述**：修复损坏的分区或子分区。
**语法**：
```
ALTER TABLE table_name REPAIR PARTITION {partition_names | ALL}
```
其中，partition_names为：
```
{partition_name | subpartition_name}
```
表12参数说明 
| **参数**            | **参数说明**               |
|:---|:---|
| table_name        | 分区表的名称（可以采用模式限定的方式引用）。 |
| partition_name    | 分区名称。                  |
| subpartition_name | 子分区名称。                 |
   
**示例**：
- 修复sales_data表的分区part_2022。
  ```
  ALTER TABLE sales_data REPAIR PARTITION part_2022;
  ```
  
- 修复sales_data表的子分区part_2022_sp1。
  ```
  ALTER TABLE sales_data REPAIR PARTITION part_2022_sp1;
  ```
  
 
 #### REMOVE PARTITION
**描述**：删除分区和子分区表的分区结构。
**语法**：
ALTER TABLE ... REMOVE PARTITIONING命令用于删除分区和子分区表的分区结构，并转化成单表，且不丢失数据。
```
ALTER TABLE table_name REMOVE PARTITIONING
```
**示例**：
删除sales_data表中所有的分区结构：
```
ALTER TABLE sales_data REMOVE PARTITIONING;
```
