#### 13.1.9.1 ALTER TABLE 分区操作

与分区相关的子句[`更改表`](alter-table.html)可与分区表一起用于重新分区、添加、删除、丢弃、导入、合并和拆分分区，以及执行分区维护。

-   只需使用*`分区选项`*子句[`更改表`](alter-table.html)在分区表上根据分区表定义的分区方案重新分区表*`分区选项`*.这个子句总是以`分区方式`, 并遵循与适用于*`分区选项`*条款[`创建表`](create-table.html)（有关更多详细信息，请参阅[第 13.1.20 节，“CREATE TABLE 语句”](create-table.html))，也可用于对尚未分区的现有表进行分区。例如，考虑如下所示定义的（非分区）表：

    ```
    CREATE TABLE t1 (
        id INT,
        year_col INT
    );
    ```

    这个表可以被分区`哈希`， 使用`id`列作为分区键，通过以下语句分为 8 个分区：

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

    MySQL 支持一个`算法`选项`[SUB]通过[LINEAR]键进行分区`.`算法=1`导致服务器在计算分区中行的位置时使用与 MySQL 5.1 相同的键散列函数；`算法=2`意味着服务器使用默认实现和使用的键散列函数用于新的`钥匙`MySQL 5.5 及更高版本中的分区表。（使用 MySQL 5.5 和更高版本中使用的键散列函数创建的分区表不能被 MySQL 5.1 服务器使用。）不指定选项与使用相同的效果`算法=2`.此选项主要用于升级或降级时`[线性]键`MySQL 5.1 和更高版本 MySQL 之间的分区表，或用于创建分区表`钥匙`要么`线性键`在 MySQL 5.5 或更高版本的服务器上，可以在 MySQL 5.1 服务器上使用。

    使用`ALTER TABLE ... 分区`语句必须遵循与使用创建的相同的规则`创建表...分区依据`.这包括管理表可能具有的任何唯一键（包括任何主键）与分区表达式中使用的一个或多个列之间关系的规则，如在[第 24.6.1 节，“分区键、主键和唯一键”](partitioning-limitations-partitioning-keys-unique-keys.html).这`创建表...分区依据`指定分区数的规则也适用于`ALTER TABLE ... 分区`.

    这*`分区定义`*条款`更改表添加分区`支持与同名子句相同的选项[`创建表`](create-table.html)陈述。（看[第 13.1.20 节，“CREATE TABLE 语句”](create-table.html)，用于语法和描述。）假设您已创建分区表，如下所示：

    ```
    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));
    ```

    `删除分区`可用于丢弃一个或多个`范围`要么`列表`分区。此语句不能与`哈希`要么`钥匙`分区；相反，使用`合并分区`（见本节后面）。存储在已删除分区中的任何数据*`分区名称`*列表被丢弃。例如，给定表`t1`之前定义的，您可以删除名为的分区`p0`和`p1`如此处所示：

    ```
    ALTER TABLE t1 DROP PARTITION p0, p1;
    ```

    笔记

    `删除分区`不适用于使用[`新开发银行`](mysql-cluster.html)存储引擎。看[第 24.3.1 节，“RANGE 和 LIST 分区的管理”](partitioning-management-range-list.html)， 和[第 23.2.7 节，“NDB Cluster 的已知限制”](mysql-cluster-limitations.html).

    `添加分区`和`删除分区`目前不支持`如果 [不] 存在`.

    这[`丢弃分区...表空间`](alter-table.html)和[`导入分区...表空间`](alter-table.html)选项扩展[可传输表空间](glossary.html#glos_transportable_tablespace)个人特色`InnoDB`表分区。每个`InnoDB`表分区有自己的表空间文件（`.ibd`文件）。这[可传输表空间](glossary.html#glos_transportable_tablespace)该功能可以轻松地将表空间从正在运行的 MySQL 服务器实例复制到另一个正在运行的实例，或者在同一实例上执行恢复。这两个选项都采用逗号分隔的一个或多个分区名称列表。例如：

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

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

    跑步时[`丢弃分区...表空间`](alter-table.html)和[`导入分区...表空间`](alter-table.html)在子分区表上，允许使用分区和子分区名称。指定分区名称时，将包括该分区的子分区。

    这[可传输表空间](glossary.html#glos_transportable_tablespace)功能还支持复制或恢复分区`InnoDB`表。有关详细信息，请参阅[第 15.6.1.3 节，“导入 InnoDB 表”](innodb-table-import.html).

    支持重命名分区表。您可以使用间接重命名单个分区`ALTER TABLE ...重新组织分区`;但是，此操作会复制分区的数据。

    要从选定分区中删除行，请使用`截断分区`选项。此选项采用一个或多个以逗号分隔的分区名称的列表。考虑表格`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.html)陈述：

    ```
    DELETE FROM t1 WHERE year_col < 1991;
    ```

    截断多个分区时，分区不必是连续的：这可以大大简化对分区表的删除操作，否则这些操作需要非常复杂`在哪里`条件如果完成[`删除`](delete.html)陈述。例如，此语句从分区中删除所有行`p1`和`p3`：

    ```
    ALTER TABLE t1 TRUNCATE PARTITION p1, p3;
    ```

    等价的[`删除`](delete.html)声明显示在这里：

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

    如果您使用`全部`关键字代替分区名称列表，该语句作用于所有表分区。

    `截断分区`仅删除行；它不会改变表本身或其任何分区的定义。

    要验证是否删除了行，请检查`INFORMATION_SCHEMA.PARTITIONS`表，使用如下查询：

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

    `合并分区`可以与分区的表一起使用`哈希`要么`钥匙`减少分区的数量*`数字`*.假设您已经创建了表`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;
    ```

    最后包含的数据*`数字`*分区被合并到剩余的分区中。在这种情况下，分区 4 和 5 被合并到前 4 个分区中（分区编号为 0、1、2 和 3）。

    要更改分区表使用的部分但不是全部分区，您可以使用`重组分区`.该语句可以以多种方式使用：

    -   将一组分区合并为一个分区。这是通过在*`分区名称`*列出并提供单一定义*`分区定义`*.

    -   将现有分区拆分为多个分区。通过将单个分区命名为*`分区名称`*并提供多个*`分区定义`*.

    -   更改使用定义的分区子集的范围`值小于`或使用定义的分区子集的值列表`价值观`.

    笔记

    对于未显式命名的分区，MySQL 自动提供默认名称`p0`,`p1`,`p2`， 等等。对于子分区也是如此。

    有关更多详细信息和示例`ALTER TABLE ...重新组织分区`陈述，见[第 24.3.1 节，“RANGE 和 LIST 分区的管理”](partitioning-management-range-list.html).

-   要与表交换表分区或子分区，请使用`ALTER TABLE ...交换分区`语句——也就是说，将分区或子分区中的任何现有行移动到非分区表中，并将非分区表中的任何现有行移动到表分区或子分区中。

    一旦一个或多个列被添加到一个分区表中，使用`算法=即时`，不再可能与该表交换分区。

    有关使用信息和示例，请参阅[第 24.3.3 节，“用表交换分区和子分区”](partitioning-management-exchange.html).

-   几个选项提供分区维护和修复功能，类似于通过语句为非分区表实现的功能，例如[`检查表`](check-table.html)和[`维修台`](repair-table.html)（分区表也支持此功能；有关更多信息，请参阅[第13.7.3节，“表格维护声明”](table-maintenance-statements.html)).这些包括`分析分区`,`检查分区`,`优化分区`,`重建分区`和`修复分区`.每个选项都需要*`分区名称`*由一个或多个分区名称组成的子句，用逗号分隔。分区必须已经存在于目标表中。你也可以使用`全部的`关键字代替*`分区名称`*，在这种情况下，该语句作用于所有表分区。有关更多信息和示例，请参阅[第24.3.4节“隔板的维护”](partitioning-maintenance.html).

    [`InnoDB`](innodb-storage-engine.html)目前不支持分区优化；`改变桌子。。。优化分区`导致重建和分析整个表，并发出相应的警告。（Bug#11751825，Bug#42822）要解决此问题，请使用`改变桌子。。。重建分区`和`改变桌子。。。分析分区`相反

    这个`分析分区`, `检查分区`, `优化分区`和`修复分区`未分区的表不支持选项。

-   `删除分区`使您能够删除表的分区，而不会影响表或其数据。此选项可以与其他选项结合使用[`改变桌子`](alter-table.html)选项，例如用于添加、删除或重命名列或索引的选项。

-   使用`发动机`选择与[`改变桌子`](alter-table.html)在不影响分区的情况下更改表使用的存储引擎。目标存储引擎必须提供自己的分区处理程序。只有`InnoDB`和`NDB`存储引擎有本机分区处理程序；`NDB`MySQL 8.0目前不支持。

    这是可能的[`改变桌子`](alter-table.html)包含`分区方式`要么`删除分区`条款中除了其他变更规范，但`分区方式`要么`删除分区`子句必须在任何其他规范之后最后指定。

    这`添加分区`,`删除分区`,`合并分区`,`重组分区`,`分析分区`,`检查分区`， 和`修复分区`选项不能与其他更改规范组合在一起`更改表`，因为刚刚列出的选项作用于各个分区。有关详细信息，请参阅[第 13.1.9.1 节，“ALTER TABLE 分区操作”](alter-table-partition-operations.html).

    在给定的情况下，只能使用以下任一选项的单个实例[`更改表`](alter-table.html)陈述：`分区方式`, `添加分区`, `删除分区`, `截断分区`, `交换分区`, `重组分区`， 要么`合并分区`, `分析分区`, `检查分区`, `优化分区`, `重建分区`, `删除分区`.

    例如，以下两个语句是无效的：


```
ALTER TABLE t1 ANALYZE PARTITION p1, ANALYZE PARTITION p2;

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

在第一种情况下，您可以分析分区`p1`和`p2`表的`t1`同时使用单个语句和单个`分析分区`列出要分析的两个分区的选项，如下所示：

```
ALTER TABLE t1 ANALYZE PARTITION p1, p2;
```

在第二种情况下，无法执行`分析`和`查看`同时对同一张表的不同分区进行操作。相反，您必须发出两个单独的语句，如下所示：

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

`重建`当前不支持子分区的操作。这`重建`子分区明确不允许使用关键字，并导致`更改表`如果这样使用，则失败并出现错误。

`检查分区`和`修复分区`当要检查或修复的分区包含任何重复的键错误时，操作会失败。

有关这些声明的更多信息，请参阅[第 24.3.4 节，“分区维护”](partitioning-maintenance.html).
