All Products
Search
Document Center

PolarDB:Convert a non-partitioned table into a partitioned table

Last Updated:Mar 12, 2025

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_id single column, make sure that the primary key and unique keys include the order_id column. For example, you can define the primary key of the table by using the PRIMARY KEY(id, order_id) clause.

  • If you partition a table based on the region_id and order_date columns, make sure that the primary key and unique keys include the region_id and order_date columns. For example, you can define the primary key of the table by using the PRIMARY 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.

    Note

    The 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.

Note

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.

  1. Create a non-partitioned table named test_users and 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');
  2. Convert the test_users table 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.

  1. Create a non-partitioned table named orders and 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);
  2. Convert the orders table 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

What do I do if the "A PRIMARY KEY/UNIQUE INDEX must include all columns in the table's partitioning function" error message is displayed when I convert a non-partitioned table into a partitioned table?

You can use one of the following methods to resolve this issue:

  • Modify the primary key and unique key of the table to include the partition key columns. For more information, see Prerequisites. Examples:

    • If you partition a table based on the order_id single column, make sure that the primary key and unique keys contain the order_id column. For example, you can define the primary key of the table by using the PRIMARY KEY(id, order_id) clause.

    • If you partition a table based on the region_id and order_date columns, make sure that the primary key and unique keys contain the region_id and order_date columns. For example, you can define the primary key of the table by using the PRIMARY KEY(id, region_id, order_date) clause.

  • Configure the UNIQUE CHECK IGNORE (UCI) parameter to allow the primary key and unique keys to exclude the partition key columns. You can select a column as the partition key based on your business requirements.

References

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.