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

PolarDB:分散テーブルとレプリケートされたテーブルの作成と管理

最終更新日:Nov 09, 2025

ビジネスの成長に伴い、単一テーブルのパフォーマンスと容量がボトルネックになる可能性があります。従来のソリューションは、単一サーバーのハードウェアをアップグレードする垂直スケーリング (スケールアップ) です。しかし、このアプローチは、費用対効果と物理的な容量の点で、すぐに限界に達します。水平スケーリング (スケールアウト) は、複数のサーバーにデータを分散させることで、よりスケーラブルなソリューションを提供します。PolarDB for PostgreSQL (Distributed) クラスターは水平スケーリングを使用し、データ分布を管理するために 2 種類の特別なテーブルタイプを導入しています。大規模なデータセット用の分散テーブルと、頻繁に結合される小規模なデータセット用のレプリケートされたテーブルです。このトピックでは、これら 2 種類のテーブルの作成と管理について説明します。

分散テーブルの作成

分散テーブルの作成は、水平データ分割における中心的なステップです。ユーザーテーブルや注文詳細テーブルなど、大量のデータを格納するビジネス テーブルに適しています。これは 2 ステップのプロセスです。まず、標準テーブルを作成します。次に、create_distributed_table 関数を使用して分散テーブルに変換します。

1. 分布列の選択

分布列は、データが異なるデータノード (DN) にどのように分散されるかを決定するためのキーです。システムは、指定された列のハッシュ値を使用してデータ行をルーティングします。

  • 選択の原則: テーブルのプライマリキーまたは一意の識別子を分布列として選択します。これにより、データが均等に分散されることが保証されます。

  • 重要な制限事項: テーブルにプライマリキーまたは一意制約がある場合、分布列は制約を構成する列のいずれかである必要があります。

: 標準テーブル t を分散テーブルに変換し、id 列を分布列として使用します。

  1. t という名前の標準テーブルを作成します。

    CREATE TABLE t (id int primary key, data text);
  2. 分散テーブルに変換し、id 列を分布列として使用します。

    SELECT create_distributed_table('t', 'id');

    次の結果が返されます。

     create_distributed_table 
    --------------------------
     
    (1 row)

2. (オプション) シャード数の指定

シャードは、分散テーブルの物理的なストレージユニットです。デフォルトでは、各分散テーブルは 32 個のシャードで作成されます。テーブル作成時にシャード数を明示的に指定することも、polar_cluster.shard_count パラメーターを使用してグローバルに設定することもできます。

: 4 つのシャードを持つ分散テーブルを作成します。

  1. t1 という名前の標準テーブルを作成します。

    CREATE TABLE t1 (id int primary key, data text);
  2. シャード数を明示的に指定します。

    shard_count パラメーターの使用

    1. shard_count パラメーターを使用して、変換中にシャード数を指定します。

      SELECT create_distributed_table('t1', 'id', shard_count := 4);

      次の結果が返されます。

       create_distributed_table 
      --------------------------
       
      (1 row)
    2. シャード数をクエリします。

      SELECT * FROM pg_dist_shard WHERE logicalrelid = 't1'::regclass;

      次の結果が返されます。

      logicalrelid | shardid | shardstorage | shardminvalue | shardmaxvalue 
      --------------+---------+--------------+---------------+---------------
       t1           |  102072 | t            | -2147483648   | -1073741825
       t1           |  102073 | t            | -1073741824   | -1
       t1           |  102074 | t            | 0             | 1073741823
       t1           |  102075 | t            | 1073741824    | 2147483647
      (4 rows)

    polar_cluster.shard_count パラメーターの使用

    1. polar_cluster.shard_count パラメーターを使用して、シャード数をグローバルに設定します。

       SET polar_cluster.shard_count TO 4;
    2. テーブルを分散テーブルに変換します。

      SELECT create_distributed_table('t1', 'id');

      次の結果が返されます。

       create_distributed_table 
      --------------------------
       
      (1 row)
    3. シャード数をクエリします。

      SELECT * FROM pg_dist_shard WHERE logicalrelid = 't1'::regclass;

      次の結果が返されます。

      logicalrelid | shardid | shardstorage | shardminvalue | shardmaxvalue 
      --------------+---------+--------------+---------------+---------------
       t1           |  102072 | t            | -2147483648   | -1073741825
       t1           |  102073 | t            | -1073741824   | -1
       t1           |  102074 | t            | 0             | 1073741823
       t1           |  102075 | t            | 1073741824    | 2147483647
      (4 rows)

3. (オプション) コロケーショングループを使用した JOIN パフォーマンスの最適化

多くのビジネスアプリケーションでは、単一のエンティティに関する情報が複数のテーブルにまたがって格納されることがよくあります。関連するすべての情報を取得するには、JOIN クエリが必要です。たとえば、user_info テーブルにはすべてのユーザーデータが格納され、user_order テーブルにはすべてのユーザーの注文が格納されます。これら 2 つのテーブルは、user_id で結合する必要があります。

分散データベースでは、これらのテーブルのデータが異なるノードに分散している場合、結合クエリはノード間のデータ転送をトリガーします。これにより、高いオーバーヘッドが発生します。この問題に対処するために、PolarDB for PostgreSQL (Distributed) はコロケーショングループの概念を導入しています。

  • 機能: 複数のテーブルから同じ分散キー値を持つ行が、物理的に同じデータノードに格納されることを保証します。たとえば、user_id が 1001 であるすべての関連レコードが一緒に保持されます。これにより、分散キーに対する JOIN 操作を単一ノードで効率的に実行でき、ローカルクエリに匹敵するパフォーマンスを提供します。

  • 使用方法: PolarDB for PostgreSQL (Distributed) は、コロケーショングループを管理する 2 つの方法を提供します。暗黙的な方法 (デフォルトの動作) と明示的な方法 (推奨される方法) です。

    • デフォルトのコロケーション (暗黙的な動作): colocate_with パラメーターを指定せずに分散テーブルを作成すると、システムは自動的にデフォルトのコロケーショングループに配置します。このグループ化は、分布列の型シャード数という 2 つのプロパティに基づいています。これは、同じ分布列の型とシャード数を持つテーブルが、デフォルトでコロケーションされていると見なされることを意味します。

      説明

      デフォルトのコロケーション (暗黙的な動作): 2 つの分散テーブルが同じ分布列のデータ型とシャード数を持っていても、それらのデータが必ずしも関連しているとは限りません。

    • 明示的な制御 (推奨される方法): デフォルトの動作では、関連のないビジネス テーブルが誤ってグループ化されてしまう可能性があります。テーブルのコロケーションを正確に制御するには、関係を明示的に宣言します。

      1. コロケーショングループの最初のテーブルを作成するときは、create_distributed_table 関数で colocate_with := 'none' を設定します。これにより、テーブル用に新しい独立したコロケーショングループが作成されます。

      2. コロケーションする必要がある後続のテーブルを作成するときは、colocate_with := 'first_table_name' を設定して、既存のコロケーショングループに追加します。

: ユーザーテーブルと注文テーブルを 1 つのコロケーショングループに配置し、動物関連のテーブルを別のコロケーショングループに配置します。

  1. ユーザーと注文に関連するテーブルを作成し、同じコロケーショングループに配置します。

    -- 新しいコロケーショングループを作成
    CREATE TABLE user_info (user_id int, user_data text);
    SELECT create_distributed_table('user_info', 'user_id', colocate_with := 'none');
    -- 既存のコロケーショングループに追加
    CREATE TABLE user_order (user_id int, order_id int, order_data text);
    SELECT create_distributed_table('user_order', 'user_id', colocate_with := 'user_info');
  2. 動物関連のテーブルを作成し、別のコロケーショングループに配置します。

    -- 新しいコロケーショングループを作成
    CREATE TABLE animal (animal_id int, animal_data text);
    SELECT create_distributed_table('animal', 'animal_id', colocate_with := 'none');
    -- 既存のコロケーショングループに追加
    CREATE TABLE animal_class (animal_id int, class_id int, class_data text);
    SELECT create_distributed_table('animal_class', 'animal_id', colocate_with := 'animal');
  3. 2 つの分散テーブルのグループが異なるコロケーション ID を持っていることを確認します。これにより、それらが別々のコロケーショングループに追加されたことが確認されます。

    SELECT table_name, colocation_id, polar_cluster_table_type, distribution_column, shard_count
    FROM polar_cluster_tables
    WHERE table_name IN (
      'user_info'::regclass, 'user_order'::regclass,
      'animal'::regclass, 'animal_class'::regclass)
    ORDER BY colocation_id;

    次の結果が返されます。

      table_name  | colocation_id | polar_cluster_table_type | distribution_column | shard_count 
    --------------+---------------+--------------------------+---------------------+-------------
     user_info    |             3 | distributed              | user_id             |           4
     user_order   |             3 | distributed              | user_id             |           4
     animal       |             4 | distributed              | animal_id           |           4
     animal_class |             4 | distributed              | animal_id           |           4
    (4 rows)

レプリケートされたテーブルの作成

レプリケートされたテーブル (参照テーブルとも呼ばれます) は、そのデータの完全なコピーをすべてのデータノードに格納します。国別コードや製品カテゴリなど、分散テーブルと頻繁に結合される少量の公開データやディメンションテーブルの格納に適しています。

  • 利点: ノード間のクエリを回避し、結合操作を高速化します。

  • コスト: 書き込み操作はすべてのノードで同期されるため、高いオーバーヘッドが発生します。このため、レプリケートされたテーブルは、頻繁に変更されるデータには適していません。

: レプリケートされたテーブルを作成します。

  1. t_reference という名前の標準テーブルを作成します。

    CREATE TABLE t_reference (id int primary key, data text);
  2. レプリケートされたテーブルに変換します。この操作では、テーブル名を指定するだけで済みます。

    SELECT create_reference_table('t_reference');

    次の結果が返されます。

     create_reference_table 
    ------------------------
     
    (1 row)
  3. レプリケートされたテーブルの情報をクエリします。出力は、レプリケートされたテーブルがすべてのノードに同じ名前のシャードを持っていることを示しています。

    SELECT table_name, polar_cluster_table_type, distribution_column, shard_count
    FROM polar_cluster_tables
    WHERE table_name = 't_reference'::regclass;

    次の結果が返されます。

     table_name  | polar_cluster_table_type | distribution_column | shard_count 
    -------------+--------------------------+---------------------+-------------
     t_reference | reference                | <none>              |           1
    (1 row)
    SELECT table_name, shardid, nodename, nodeport
    FROM polar_cluster_shards
    WHERE table_name = 't_reference'::regclass;

    次の結果が返されます。

     table_name  | shardid |   nodename     | nodeport 
    -------------+---------+----------------+----------
     t_reference |  102096 | 10.xxx.xxx.xxx |     3007
     t_reference |  102096 | 10.xxx.xxx.xxx |     3020
     t_reference |  102096 | 10.xxx.xxx.xxx |     3006
     t_reference |  102096 | 10.xxx.xxx.xxx |     3003
    (4 rows)

分散テーブルの管理

分散テーブルを標準テーブルに戻す

分散機能が不要になった場合は、undistribute_table 関数を使用して、分散テーブルまたはレプリケートされたテーブルを標準テーブルに戻すことができます。データはすべてのシャードから自動的に収集され、プライマリコーディネーターノード (CN) に移動されます。

: 分散テーブル t を標準テーブルに戻します。

SELECT undistribute_table('t');

次の結果が返されます。

NOTICE:  creating a new table for public.t
NOTICE:  moving the data of public.t
NOTICE:  dropping the old public.t
NOTICE:  renaming the new table to public.t
 undistribute_table 
--------------------
 
(1 row)

その他の DDL 操作

既存の分散テーブルに対しては、標準の PostgreSQL テーブルと同様に、他のデータ定義言語 (DDL) 操作を実行できます。これらの操作は、論理テーブルと物理テーブルの構造の一貫性を保つために、すべての物理シャードに自動的に伝播されます。

  • テーブルの削除: DROP TABLE table_name;

  • インデックスの作成: CREATE INDEX index_name ON table_name (column_name);