When a non-partitioned table exceeds 1 billion rows or 1 TB of data, we recommend that you convert the non-partitioned table into a partitioned table. This topic describes how to convert a non-partitioned table into a partitioned table by using the ALTER TABLE statement.
Prerequisites
To convert a non-partitioned table that has a primary key and unique keys into a partitioned table, make sure that the primary key and unique keys include the partition key. This ensures the uniqueness of data within each partition and across all partitions. For more information, see Examples.
Examples:
If you partition a table based on the
order_idsingle column, make sure that the primary key and unique keys include theorder_idcolumn. For example, you can define the primary key of the table by using thePRIMARY KEY(id, order_id)clause.If you partition a table based on the
region_idandorder_datecolumns, make sure that the primary key and unique keys include theregion_idandorder_datecolumns. For example, you can define the primary key of the table by using thePRIMARY KEY(id, region_id, order_date)clause.
Usage notes
When you convert a non-partitioned table into a partitioned table, all existing data from the non-partitioned table is read, reorganized, and written into the new partitioned table, which is classified as a COPY DDL operation. The conversion process can be time-consuming. During the conversion process, the system blocks all DML operations on the table.
NoteThe COPY DDL algorithm copies all data from the original table to the new table. During the data replication process, the system applies a SHARED_NO_WRITE (SNW) lock on the original table. The SNW lock allows read operations but blocks all write operations on the table, which may have a significant impact on your business. For more information, see DDL algorithms.
If you want to convert a non-partitioned table into a range-partitioned table based on a time-based column and place all existing data into a single historical partition, see Convert a non-partitioned table into a range-partitioned table.
Supported partitioned table types
The database supports the conversion of non-partitioned tables into various partitioned table types, including hash-partitioned, range-partitioned, and list-partitioned table types. For more information about the partitioned table types, see Partitioned table types and Interval range partitioning.
Syntax
ALTER TABLE table_name
PARTITION BY RANGE {(expr) | COLUMNS(column_list)}
(partition_definition [, partition_definition] ...);The partition_definition clause defines how each partition is structured, which must align with the rules for the specified partitioning type.
For information about the partitioned table types supported by PolarDB for MySQL and their usage, see Partitioned table types.
Examples
Single-column partitioning
In this example, the test_users table is used to describe how to convert a non-partitioned table into a partitioned table.
Create a non-partitioned table named
test_usersand insert data into the table.CREATE TABLE test_users ( id INT AUTO_INCREMENT, region_id INT NOT NULL, -- Partition key. email VARCHAR(100) NOT NULL, name VARCHAR(50), created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, PRIMARY KEY (id, region_id), -- The primary key must include the partition key. UNIQUE KEY (email, region_id) -- The unique key must include the partition key. );INSERT INTO test_users (region_id, email, name) VALUES (1, 'alice@example.com', 'Alice'), (2, 'bob@example.com', 'Bob'), (3, 'charlie@example.com', 'Charlie');Convert the
test_userstable into a partitioned table.Convert the test_users table into a list-partitioned table. For more information, see LIST.
ALTER TABLE test_users PARTITION BY LIST (region_id) ( PARTITION p_east VALUES IN (1, 2), -- Rows whose region_id values are 1 or 2 are distributed into the p_east partition. PARTITION p_west VALUES IN (3) -- Rows whose region_id values are 3 are distributed into the p_west partition. );Convert the test_users table into a hash-partitioned table. For more information, see HASH.
ALTER TABLE test_users PARTITION BY HASH(region_id) PARTITIONS 4; -- Distribute the table data into four partitions.Convert the test_users table into a range-partitioned table. For more information, see RANGE.
ALTER TABLE test_users PARTITION BY RANGE (region_id) ( PARTITION p0 VALUES LESS THAN (2), -- region_id < 2 PARTITION p1 VALUES LESS THAN (3), --Rows whose region_id values are between 2 (inclusive) and 3 (exclusive) are distributed to partition p1. PARTITION p2 VALUES LESS THAN MAXVALUE );
Multi-column partitioning
In this example, the orders table is used to describe how to convert a non-partitioned table into a partitioned table.
Create a non-partitioned table named
ordersand insert data into the table.CREATE TABLE orders ( order_id INT AUTO_INCREMENT, region_id INT NOT NULL, -- Partition key field 1. order_date DATE NOT NULL, -- Partition key field 2. customer_id INT, amount DECIMAL(10,2), PRIMARY KEY (order_id, region_id, order_date), -- The primary key must contain all columns of the partition key. UNIQUE KEY (customer_id, order_id, region_id, order_date) -- The unique key must contain all columns of the partition key. );INSERT INTO orders (region_id, order_date, customer_id, amount) VALUES (1, '2022-12-31', 1001, 99.99), (1, '2023-05-01', 1002, 199.99), (2, '2023-06-01', 1003, 299.99);Convert the
orderstable into a range partitioned table. For more information, see RANGE.ALTER TABLE orders PARTITION BY RANGE COLUMNS(region_id, order_date) ( PARTITION p0 VALUES LESS THAN (1, '2023-01-01'), -- Rows whose region_id values is 1 or less than 1 and whose order_date value is before January 1, 2023 are distributed to partition p0. PARTITION p1 VALUES LESS THAN (2, '2024-01-01'), -- Rows whose region_id values is 2 or less than 2 and whose order_date value is before January 1, 2024 are distributed to partition p1. PARTITION p2 VALUES LESS THAN (MAXVALUE, MAXVALUE) );
FAQ
References
Interval range partitioning: an extension of range partitioning. This method allows the database to automatically create new partitions when inserted data falls outside the ranges of existing partitions.
Convert a non-partitioned table into a range-partitioned table: If you want to partition a table based on a time-based column and organize all data into a single historical partition, you can use this method.
Expert service
For more information about how to convert a non-partitioned table into a partitioned table, join the DingTalk group 24490017825 to obtain technical support. The experts in the group can answer your questions.