メインコンテンツへスキップ
SaaS のデータ分析プラットフォームでは、組織、顧客、事業部門などの複数のテナントが、それぞれのデータを論理的に分離したまま、同じデータベースインフラストラクチャを共有することが一般的です。これにより、異なるユーザーが同一プラットフォーム内で自分のデータに安全にアクセスできます。 要件に応じて、マルチテナンシーを実装する方法はいくつかあります。以下では、ClickHouse Cloud を使用してこれらを実装する方法を紹介します。

共有テーブル

このアプローチでは、すべてのテナントのデータを 1 つの共有テーブルに保存し、各テナントのデータを識別するためのフィールド (または複数フィールドの組み合わせ) を使用します。パフォーマンスを最大化するには、このフィールドを 主キー に含める必要があります。各テナントが自分に属するデータにのみアクセスできるようにするために、ロールベースのアクセス制御 を使用し、これを 行ポリシー で実装します。
このアプローチは、特にすべてのテナントで同じデータスキーマが使われ、データ量が中程度 (数 TB 未満) である場合に、最も管理しやすいため推奨します
すべてのテナントデータを 1 つのテーブルに集約することで、データ圧縮の最適化とメタデータのオーバーヘッド削減により、ストレージ効率が向上します。さらに、すべてのデータを一元管理できるため、スキーマの更新も簡単になります。 この方法は、非常に多くのテナント (場合によっては数百万) を扱う場合に特に効果的です。 ただし、テナントごとにデータスキーマが異なる場合や、時間の経過とともに差異が大きくなることが見込まれる場合は、別のアプローチの方が適していることがあります。 テナント間でデータ量に大きな差がある場合、小規模なテナントのクエリ性能に不要な影響が生じる可能性があります。なお、この問題はテナント識別用フィールドを主キーに含めることで大幅に軽減されます。

これは、共有テーブルを用いたマルチテナンシーモデルの実装例です。 まず、tenant_id フィールドを主キーに含む共有テーブルを作成します。
ダミーデータを挿入してみましょう。
それでは、user_1user_2 の2人のユーザーを作成しましょう。
user_1user_2 がそれぞれ自分のテナントのデータにのみアクセスできるようにする行ポリシーを作成します
次に、共通ロールを使用して、共有テーブルに対してGRANT SELECT権限を付与します。
これで user_1 として接続し、簡単な SELECT を実行できます。返されるのは最初のテナントの行のみです。

テーブルを分ける

このアプローチでは、各テナントのデータを同じデータベース内の別々のテーブルに格納するため、テナントを識別するための特定のフィールドは不要です。ユーザーアクセスは GRANT ステートメント によって制御されるため、各ユーザーは自分のテナントのデータを含むテーブルにのみアクセスできます。
テナントごとにデータスキーマが異なる場合は、テーブルを分けるのが適しています。
少数のテナントが非常に大規模なデータセットを持ち、クエリ性能が重要なシナリオでは、このアプローチは共有テーブルモデルより高い性能を発揮する可能性があります。他のテナントのデータを除外するためのフィルタが不要なため、クエリをより効率的に実行できます。さらに、主キーに追加のフィールド (テナント ID など) を含める必要がないため、主キーをさらに最適化できます。 このアプローチは数千ものテナントにはスケールしない点に注意してください。使用制限 を参照してください。

これは、テーブル分離マルチテナンシーモデルの実装例です。 まず、tenant_1 からのイベント用と tenant_2 からのイベント用に、2つのテーブルを作成しましょう。
ダミーデータを挿入しましょう。
次に、user_1user_2 という2つのユーザーを作成します。
次に、対応するテーブルに GRANT SELECT 権限を付与します。
これで user_1 として接続し、このユーザーに対応するテーブルに対して簡単なSELECTを実行できます。最初のテナントの行のみが返されます。

データベースの分離

各テナントのデータは、同じ ClickHouse サービス 内の個別のデータベースに保存されます。
このアプローチは、各テナントで多数のテーブルや、場合によっては materialized view が必要で、データスキーマもそれぞれ異なる場合に有効です。ただし、テナント数が多いと管理が難しくなる可能性があります。
実装はテーブルを分離するアプローチと似ていますが、テーブルレベルではなく、データベースレベルで権限を付与します。 このアプローチは数千規模のテナントにはスケールしない点に注意してください。使用制限を参照してください。

これは、データベースを分離するマルチテナンシーモデルの実装例です。 まず、tenant_1 用と tenant_2 用に、2つのデータベースを作成します。
ダミーデータを挿入しましょう。
次に、user_1user_2 の2人のユーザーを作成します。
次に、対応するテーブルに対して GRANT SELECT 権限を付与します。
これで user_1 として接続し、該当するデータベースの events テーブルに対して簡単な SELECT クエリを実行できます。返されるのは、最初のテナントの行のみです。

コンピュート-コンピュート分離

前述の 3 つのアプローチは、Warehouse を使用することで、さらに分離できます。データは共通のオブジェクトストレージを通じて共有されますが、コンピュート-コンピュート分離 により、各テナントは CPU/メモリ比の異なる独自のコンピュートサービスを持つことができます。 ユーザー管理は、前述のアプローチと同様です。これは、Warehouse 内のすべてのサービスが同じアクセス制御を共有するためです。 Warehouse 内の子サービス数は少数に制限されている点に注意してください。Warehouse の制限事項を参照してください。

個別のクラウドサービス

最も極端なアプローチは、テナントごとに別々の ClickHouse サービスを使用することです。
この方法はあまり一般的ではありませんが、法的要件、セキュリティ上の理由、または地理的な近接性の観点から、テナントデータを異なるリージョンに保存する必要がある場合には有効な選択肢となります。
各ユーザーがそれぞれのテナントのデータにアクセスできるようにするには、各サービス上にユーザーアカウントを作成する必要があります。 このアプローチは管理が難しく、各サービスの実行にそれぞれ独自のインフラストラクチャが必要になるため、サービスごとに運用負荷も増えます。サービスは ClickHouse Cloud API を介して管理でき、公式 Terraform プロバイダー を使ったオーケストレーションも可能です。

これは、サービスを分離したマルチテナンシーモデルの実装例です。この例では、1 つの ClickHouse サービス上でテーブルとユーザーを作成していますが、同じ内容をすべてのサービスにも反映する必要があります。 まず、テーブル events を作成します
ダミーデータを挿入してみましょう。
では、2人のユーザー user_1 を作成しましょう
次に、該当するテーブルに GRANT SELECT 権限を付与します。
これで、テナント 1 のサービスに user_1 として接続し、簡単なselectを実行できます。返されるのは、最初のテナントの行だけです。
最終更新日 2026年6月12日