すべてのプロダクト
Search
ドキュメントセンター

PolarDB:非パーティションテーブルをパーティションテーブルに変換する

最終更新日:Mar 13, 2025

非パーティションテーブルの行数が 10 億行を超えるか、データサイズが 1 TB を超える場合は、非パーティションテーブルをパーティションテーブルに変換することをお勧めします。このトピックでは、ALTER TABLE 文を使用して非パーティションテーブルをパーティションテーブルに変換する方法について説明します。

前提条件

プライマリキーとユニークキーを持つ非パーティションテーブルをパーティションテーブルに変換するには、プライマリキーとユニークキーにパーティションキーが含まれていることを確認してください。これにより、各パーティション内およびすべてのパーティションにわたるデータの一意性が確保されます。詳細については、「」をご参照ください。

例:

  • order_id 単一列に基づいてテーブルをパーティション分割する場合は、プライマリキーとユニークキーに order_id 列が含まれていることを確認してください。たとえば、PRIMARY KEY(id, order_id) 句を使用してテーブルのプライマリキーを定義できます。

  • region_id 列と order_date 列に基づいてテーブルをパーティション分割する場合は、プライマリキーとユニークキーに region_id 列と order_date 列が含まれていることを確認してください。たとえば、PRIMARY KEY(id, region_id, order_date) 句を使用してテーブルのプライマリキーを定義できます。

注意事項

  • 非パーティションテーブルをパーティションテーブルに変換すると、非パーティションテーブルの既存のデータがすべて読み取られ、再編成されて、新しいパーティションテーブルに書き込まれます。これは COPY DDL 操作として分類されます。変換プロセスには時間がかかる場合があります。変換プロセス中は、システムはテーブルに対するすべての DML 操作をブロックします。

    説明

    COPY DDL アルゴリズムは、元のテーブルから新しいテーブルにすべてのデータをコピーします。データレプリケーションプロセス中は、システムは元のテーブルに SHARED_NO_WRITE(SNW)ロックを適用します。 SNW ロックは読み取り操作を許可しますが、テーブルへのすべての書き込み操作をブロックするため、ビジネスに大きな影響を与える可能性があります。詳細については、「DDL アルゴリズム」をご参照ください。

  • 時間ベースの列に基づいて非パーティションテーブルを範囲パーティションテーブルに変換し、既存のすべてのデータを単一の履歴パーティションに配置する場合は、「非パーティションテーブルを範囲パーティションテーブルに変換する」をご参照ください。

サポートされているパーティションテーブルタイプ

データベースは、非パーティションテーブルからさまざまなパーティションテーブルタイプへの変換をサポートしています。これには、ハッシュパーティション、範囲パーティション、リストパーティションテーブルタイプが含まれます。パーティションテーブルタイプの詳細については、「パーティションテーブルタイプ」および「間隔範囲パーティション」をご参照ください。

構文

ALTER TABLE table_name
PARTITION BY RANGE {(expr) | COLUMNS(column_list)}
(partition_definition [, partition_definition] ...);

partition_definition 句は、各パーティションの構造を定義します。これは、指定されたパーティションタイプのルールに一致している必要があります。

説明

PolarDB for MySQL でサポートされているパーティションテーブルタイプとその使用方法については、「パーティションテーブルタイプ」をご参照ください。

単一列パーティション

この例では、test_users テーブルを使用して、非パーティションテーブルをパーティションテーブルに変換する方法について説明します。

  1. test_users という名前の非パーティションテーブルを作成し、テーブルにデータを挿入します。

    CREATE TABLE test_users (
        id INT AUTO_INCREMENT,
        region_id INT NOT NULL, -- パーティションキー。
        email VARCHAR(100) NOT NULL,
        name VARCHAR(50),
        created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
        PRIMARY KEY (id, region_id), -- プライマリキーにはパーティションキーを含める必要があります。
        UNIQUE KEY (email, region_id) -- ユニークキーにはパーティションキーを含める必要があります。
    );
    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. test_users テーブルをパーティションテーブルに変換します。

    • test_users テーブルをリストパーティションテーブルに変換します。詳細については、「LIST」をご参照ください。

      ALTER TABLE test_users 
          PARTITION BY LIST (region_id) (
              PARTITION p_east VALUES IN (1, 2), -- region_id 値が 1 または 2 の行は p_east パーティションに配信されます。
              PARTITION p_west VALUES IN (3) -- region_id 値が 3 の行は p_west パーティションに配信されます。
          );
    • test_users テーブルをハッシュパーティションテーブルに変換します。詳細については、「HASH」をご参照ください。

      ALTER TABLE test_users 
          PARTITION BY HASH(region_id)
          PARTITIONS 4; -- テーブルデータを 4 つのパーティションに配信します。
    • test_users テーブルを範囲パーティションテーブルに変換します。詳細については、「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), -- region_id 値が 2 以上 3 未満の行はパーティション p1 に配信されます。
              PARTITION p2 VALUES LESS THAN MAXVALUE
          );

複数列パーティション

この例では、orders テーブルを使用して、非パーティションテーブルをパーティションテーブルに変換する方法について説明します。

  1. orders という名前の非パーティションテーブルを作成し、テーブルにデータを挿入します。

    CREATE TABLE orders (
        order_id INT AUTO_INCREMENT,
        region_id INT NOT NULL, -- パーティションキーフィールド 1。
        order_date DATE NOT NULL, -- パーティションキーフィールド 2。
        customer_id INT,
        amount DECIMAL(10,2),
        PRIMARY KEY (order_id, region_id, order_date), -- プライマリキーには、パーティションキーのすべての列が含まれている必要があります。
        UNIQUE KEY (customer_id, order_id, region_id, order_date) -- ユニークキーには、パーティションキーのすべての列が含まれている必要があります。
    );
    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. orders テーブルを範囲パーティションテーブルに変換します。詳細については、「RANGE」をご参照ください。

    ALTER TABLE orders
        PARTITION BY RANGE COLUMNS(region_id, order_date) (
            PARTITION p0 VALUES LESS THAN (1, '2023-01-01'), -- region_id 値が 1 以下で、order_date 値が 2023 年 1 月 1 日より前の行は、パーティション p0 に配信されます。
            PARTITION p1 VALUES LESS THAN (2, '2024-01-01'), -- region_id 値が 2 以下で、order_date 値が 2024 年 1 月 1 日より前の行は、パーティション p1 に配信されます。
            PARTITION p2 VALUES LESS THAN (MAXVALUE, MAXVALUE)
        );

FAQ

非パーティションテーブルをパーティションテーブルに変換するときに、「プライマリキー/ユニークインデックスには、テーブルのパーティション関数にあるすべての列を含める必要があります」というエラーメッセージが表示された場合はどうすればよいですか?

次のいずれかの方法を使用して、この問題を解決できます。

  • テーブルのプライマリキーとユニークキーを変更して、パーティションキー列を含めます。詳細については、「前提条件」をご参照ください。例:

    • order_id 単一列に基づいてテーブルをパーティション分割する場合は、プライマリキーとユニークキーに order_id 列が含まれていることを確認してください。たとえば、PRIMARY KEY(id, order_id) 句を使用してテーブルのプライマリキーを定義できます。

    • region_id 列と order_date 列に基づいてテーブルをパーティション分割する場合は、プライマリキーとユニークキーに region_id 列と order_date 列が含まれていることを確認してください。たとえば、PRIMARY KEY(id, region_id, order_date) 句を使用してテーブルのプライマリキーを定義できます。

  • UNIQUE CHECK IGNORE (UCI) パラメーターを設定して、プライマリキーとユニークキーにパーティションキー列を除外できるようにします。ビジネス要件に基づいて、パーティションキーとして列を選択できます。

関連情報

エキスパートサービス

非パーティションテーブルをパーティションテーブルに変換する方法の詳細については、DingTalk グループ 24490017825 に参加してテクニカルサポートを受けてください。グループのエキスパートが質問にお答えします。