このアプローチは、特にすべてのテナントで同じデータスキーマが使われ、データ量が中程度 (数 TB 未満) である場合に、最も管理しやすいため推奨しますすべてのテナントデータを 1 つのテーブルに集約することで、データ圧縮の最適化とメタデータのオーバーヘッド削減により、ストレージ効率が向上します。さらに、すべてのデータを一元管理できるため、スキーマの更新も簡単になります。 この方法は、非常に多くのテナント (場合によっては数百万) を扱う場合に特に効果的です。 ただし、テナントごとにデータスキーマが異なる場合や、時間の経過とともに差異が大きくなることが見込まれる場合は、別のアプローチの方が適していることがあります。 テナント間でデータ量に大きな差がある場合、小規模なテナントのクエリ性能に不要な影響が生じる可能性があります。なお、この問題はテナント識別用フィールドを主キーに含めることで大幅に軽減されます。 これは、共有テーブルを用いたマルチテナンシーモデルの実装例です。 まず、
tenant_id フィールドを主キーに含む共有テーブルを作成します。
user_1 と user_2 の2人のユーザーを作成しましょう。
user_1 と user_2 がそれぞれ自分のテナントのデータにのみアクセスできるようにする行ポリシーを作成します。
GRANT SELECT権限を付与します。
user_1 として接続し、簡単な SELECT を実行できます。返されるのは最初のテナントの行のみです。
テーブルを分ける
テナントごとにデータスキーマが異なる場合は、テーブルを分けるのが適しています。少数のテナントが非常に大規模なデータセットを持ち、クエリ性能が重要なシナリオでは、このアプローチは共有テーブルモデルより高い性能を発揮する可能性があります。他のテナントのデータを除外するためのフィルタが不要なため、クエリをより効率的に実行できます。さらに、主キーに追加のフィールド (テナント ID など) を含める必要がないため、主キーをさらに最適化できます。 このアプローチは数千ものテナントにはスケールしない点に注意してください。使用制限 を参照してください。 これは、テーブル分離マルチテナンシーモデルの実装例です。 まず、
tenant_1 からのイベント用と tenant_2 からのイベント用に、2つのテーブルを作成しましょう。
user_1 と user_2 という2つのユーザーを作成します。
GRANT SELECT 権限を付与します。
user_1 として接続し、このユーザーに対応するテーブルに対して簡単なSELECTを実行できます。最初のテナントの行のみが返されます。
データベースの分離
このアプローチは、各テナントで多数のテーブルや、場合によっては materialized view が必要で、データスキーマもそれぞれ異なる場合に有効です。ただし、テナント数が多いと管理が難しくなる可能性があります。実装はテーブルを分離するアプローチと似ていますが、テーブルレベルではなく、データベースレベルで権限を付与します。 このアプローチは数千規模のテナントにはスケールしない点に注意してください。使用制限を参照してください。 これは、データベースを分離するマルチテナンシーモデルの実装例です。 まず、
tenant_1 用と tenant_2 用に、2つのデータベースを作成します。
user_1 と user_2 の2人のユーザーを作成します。
GRANT SELECT 権限を付与します。
user_1 として接続し、該当するデータベースの events テーブルに対して簡単な SELECT クエリを実行できます。返されるのは、最初のテナントの行のみです。
コンピュート-コンピュート分離
個別のクラウドサービス
この方法はあまり一般的ではありませんが、法的要件、セキュリティ上の理由、または地理的な近接性の観点から、テナントデータを異なるリージョンに保存する必要がある場合には有効な選択肢となります。各ユーザーがそれぞれのテナントのデータにアクセスできるようにするには、各サービス上にユーザーアカウントを作成する必要があります。 このアプローチは管理が難しく、各サービスの実行にそれぞれ独自のインフラストラクチャが必要になるため、サービスごとに運用負荷も増えます。サービスは ClickHouse Cloud API を介して管理でき、公式 Terraform プロバイダー を使ったオーケストレーションも可能です。 これは、サービスを分離したマルチテナンシーモデルの実装例です。この例では、1 つの ClickHouse サービス上でテーブルとユーザーを作成していますが、同じ内容をすべてのサービスにも反映する必要があります。 まず、テーブル
events を作成します
user_1 を作成しましょう
GRANT SELECT 権限を付与します。
user_1 として接続し、簡単なselectを実行できます。返されるのは、最初のテナントの行だけです。