

本文属于机器翻译版本。若本译文内容与英语原文存在差异，则一律以英文原文为准。

# 归档分区表中的数据
<a name="archive-partitioned-tables"></a>

MySQL 支持对 InnoDB 存储引擎进行[分区](https://dev.mysql.com/doc/refman/8.0/en/partitioning.html)，您可以使用此功能对大型表进行分区。虽然对分区表进行操作的 SQL 会读取整个表，但表内的分区会存储为单独的物理表。这使您可以自由地从表中删除不需要的分区，而无需逐行删除，因此您可以将历史行归档在数据库中。

考虑以下示例代码。`TABLE orders` 存在于 `orderprocessing` 架构中。其历史数据存在于分区 `phistorica`l 中，该分区包含属于 2021 年及更早版本的数据。在同一个表中，2022 年每个月的实时分区中都存在应用程序级别的热数据。要归档分区 `phistorical` 中的数据，您可以在 `archive` 架构中创建具有相同结构的归档 `table orders_2021_and_older`。然后，您可以使用 MySQL [EXCHANGE PARTITION](https://dev.mysql.com/doc/refman/8.0/en/partitioning-management-exchange.html) 将该分区 `phistorical` 移动到该表中。请注意，归档表未分区。归档后，您可以验证您的数据并将其移动到 Amazon S3。

```
CREATE TABLE orders (
      orderid bigint NOT NULL AUTO_INCREMENT,
      customerid bigint DEFAULT NULL,
      ............
      ............
      order_date date NOT NULL,
      PRIMARY KEY (`orderid`,`order_date`))
    PARTITION BY RANGE (TO_DAYS(order_date)) (
          PARTITION pstart   VALUES LESS THAN (0),
          PARTITION phistorical VALUES LESS THAN (TO_DAYS('2022-01-01')),
          PARTITION p2022JAN VALUES LESS THAN (TO_DAYS('2022-02-01')),
          PARTITION p2022FEB VALUES LESS THAN (TO_DAYS('2022-03-01')),
          PARTITION p2022MAR VALUES LESS THAN (TO_DAYS('2022-04-01')),
          PARTITION p2022APR VALUES LESS THAN (TO_DAYS('2022-05-01')),
          PARTITION p2022MAY VALUES LESS THAN (TO_DAYS('2022-06-01')),
          PARTITION p2022JUN VALUES LESS THAN (TO_DAYS('2022-07-01')),
          PARTITION p2022JUL VALUES LESS THAN (TO_DAYS('2022-08-01')),
          PARTITION p2022AUG VALUES LESS THAN (TO_DAYS('2022-09-01')),
          PARTITION p2022SEP VALUES LESS THAN (TO_DAYS('2022-10-01')),
          PARTITION p2022OCT VALUES LESS THAN (TO_DAYS('2022-11-01')),
          PARTITION p2022NOV VALUES LESS THAN (TO_DAYS('2022-12-01')),
          PARTITION p2022DEC VALUES LESS THAN (TO_DAYS('2023-01-01')),
          PARTITION pfuture       VALUES LESS THAN MAXVALUE
      );
CREATE TABLE orders_2021_and_older (
        orderid bigint NOT NULL AUTO_INCREMENT,
        customerid bigint DEFAULT NULL,
        ............
        ............
        order_date date NOT NULL,
        PRIMARY KEY (`orderid`,`order_date`));
mysql> alter table orderprocessing.orders exchange partition phistorical with table archive.orders_2021_and_older;
  Query OK, 0 rows affected (0.33 sec)
```

在您使用 `EXCHANGE PARTITION` 功能归档历史数据时，我们建议使用以下最佳实践：
+ 创建一个单独的架构，用于在您的应用程序中存储归档数据。此架构将包含归档数据的归档表。归档架构中的归档表应与实时表具有相同的结构，包括其索引和主键。但是，目标归档表不能是分区表。MySQL 中不允许在两个分区表之间交换分区。
+ 遵循归档表的命名惯例，以帮助您识别存储在归档表中的历史数据。在您执行审计任务或设计将此数据移出到 Amazon S3 的作业时，这非常有用。
+ 当没有流量进入 Aurora MySQL 兼容版写入器、Amazon RDS for MySQL 或 Amazon RDS for MariaDB 实例时，在停机时间段内执行 `EXCHANGE PARTITION` 数据定义语言（DDL）语句。

  可能可以在您的应用程序或微服务的低流量窗口期间运行 `EXCHANGE PARTITION`。但是，分区表上不应有写入操作，也不能进行任何选择或选择很少。现有的长时间运行的 SELECT 查询可能会导致您的 `EXCHANGE PARTITION` DDL 等待，从而导致数据库出现资源争用。在系统上运行 `EXCHANGE PARTITION` 之前，设计脚本来验证所有这些条件是否满足。

如果您的应用程序设计可以支持分区数据，并且您当前有一个未分区的表，请考虑将数据移动到分区表中以支持归档数据。有关更多信息，请参阅 [MySQL 文档](https://dev.mysql.com/doc/refman/8.0/en/alter-table-partition-operations.html)。