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

PolarDB:マルチテナント管理

最終更新日:Mar 03, 2026

マルチテナントアプリケーションでは、ブロードキャストクエリによるパフォーマンス低下や、データ分布の不均一性に起因するリソースの無駄遣いが一般的な課題です。PolarDB for PostgreSQL (Distributed Edition) は、ネイティブのマルチテナント管理機能を提供し、行ベースのシャーディング および スキーマベースのシャーディング の 2 つのモードをサポートします。この機能により、特定のテナントに対するクエリが単一のデータノード(DN)にルーティングされ、ブロードキャストクエリを回避するとともに、効率的な読み取りおよび書き込みを実現します。また、テナント間のデータ分布を均等化することで、データスキューを防止し、リソース利用率を向上させます。

比較と選択

ビジネスシナリオおよびデータの特性に応じて、適切なシャーディングポリシーを選択してください。両ポリシーの共通の目的は、単一テナントのリクエストおよびデータを 1 つの DN に限定し、最適なパフォーマンスを達成することです。

モード

説明

推奨される利用シーン

行ベースのシャーディング

同一テーブル内のテナント ID フィールド(分布列)を用いてデータを区別します。異なるテナントのデータ行を異なる DN に分散します。

  • すべてのテナントは、まったく同じテーブル スキーマを持っています。

  • テナント数が非常に多い場合(例:10,000 以上)。

スキーマベースのシャーディング

各テナントごとに個別のスキーマを作成します。そのスキーマ全体のデータを特定の DN にルーティングします。

  • 異なるテナント間でテーブルスキーマが異なる場合。

  • マイグレーションコストを低減するため、アプリケーション層で既存のスキーマ隔離ロジックを維持したい場合。

  • テナント数が少ない場合(例:10,000 未満)。

行ベースのシャーディング

テナント ID 列を分布列として使用し、行単位でテナントデータを隔離します。

ステップ 1:分散テーブルの作成

テナント ID 列(例:tenant_id)を含むテーブルを作成します。その後、create_distributed_table 関数を呼び出して、この列を分散キーとして使用する 分散テーブル に変換します。

-- 1. テーブルを作成します。tenant_id 列はテナントを区別するために使用されます。
CREATE TABLE test_table (tenant_id text primary key, data text);

-- 2. test_table を分散テーブルとして設定し、tenant_id を分布列として指定します。
SELECT create_distributed_table('test_table', 'tenant_id');

ステップ 2:クエリルーティングの確認

特定のテナント向けにクエリを実行し、クエリプランを確認して、リクエストが単一の DN にルーティングされていることを検証します。返されたクエリプランにおいて、Task Count が 1 の場合、クエリは正常に単一の DN へプッシュダウンされています。本例では、対象ノードは 10.0.0.1:5432 です。これにより、ブロードキャストクエリが回避されます。

-- company1 テナント向けのクエリプランを表示します。
EXPLAIN SELECT * FROM test_table WHERE tenant_id = 'company1';

-- サンプル結果:
                                                       QUERY PLAN                                                       
------------------------------------------------------------------------------------------------------------------------
 Custom Scan (PolarCluster Adaptive)  (cost=0.00..0.00 rows=0 width=0)
   Task Count: 1
   Tasks Shown: All
   ->  Task
         Node: host=10.0.0.1 port=5432 dbname=testdb
         ->  Index Scan using test_table_pkey_102185 on test_table_102185 test_table  (cost=0.15..2.37 rows=1 width=64)
               Index Cond: (tenant_id = 'company1'::text)
(7 rows)

スキーマベースのシャーディング

この方法では、各テナントごとに個別の分散スキーマを作成することで、テナントデータを隔離します。

ステップ 1:スキーマの作成と分散化

単一テナント向けに専用のスキーマ(例:company_test_1)を作成し、これを 分散スキーマ として設定します。この操作により、当該スキーマ下のすべてのデータおよび操作が単一の DN にルーティングされます。

-- 1. company_test_1 テナント向けのスキーマを作成します。
CREATE SCHEMA company_test_1;

-- 2. スキーマを分散スキーマとして設定します。
SELECT polar_cluster_schema_distribute('company_test_1');

ステップ 2:テナントスキーマ内でのテーブル作成

search_path を対象テナントのスキーマに切り替え、そのスキーマ内に業務テーブルを作成します。

-- 1. company_test_1 テナントのスキーマに切り替えます。
SET search_path TO company_test_1;

-- 2. このスキーマ内に業務テーブルを作成します。
CREATE TABLE users (id SERIAL, name TEXT);
CREATE TABLE orders (id SERIAL, user_id INT);

ステップ 3:クエリルーティングの確認

search_path をテナントのスキーマに設定した後、クエリを実行し、クエリプランを確認して、リクエストが単一の DN にルーティングされていることを検証します。返されたクエリプランで Task Count が 1 である場合、当該テナントに関するすべての操作が単一ノード上で隔離されています。本例では、対象ノードは 10.0.0.1:5432 です。

-- 1. search_path が対象テナントに正しく設定されていることを確認します。
SET search_path TO company_test_1;

-- 2. クエリプランを表示します。
EXPLAIN SELECT * FROM users WHERE id = 1;

-- サンプル結果:
                                   QUERY PLAN                                   
--------------------------------------------------------------------------------
 Custom Scan (PolarCluster Adaptive)  (cost=0.00..0.00 rows=0 width=0)
   Task Count: 1
   Tasks Shown: All
   ->  Task
         Node: host=10.0.0.1 port=5432 dbname=testdb
         ->  Seq Scan on users_102191 users  (cost=0.00..25.88 rows=6 width=36)
               Filter: (id = 1)
(7 rows)