web-dev-qa-db-ja.com

マルチテナントデータベースでのtenant_idの使用

私たちは、すべての企業が独自のデータベーススキーマを使用するSASSWebアプリケーションを構築しています。 postgresqlを使用すると、パブリックスキーマにテーブル「companies」があり、会社の名前と切り替え先のスキーマの名前が保持されます。テナントスキーマには、この会社に固有のデータを格納するテーブルがたくさんあります。すべてのリクエストで、テナントスキーマは、セッションに保存されている現在の会社に基づいて設定されます。

内部の議論はこれです:

テナントスキーマのテーブルには、データと会社の関係を示す_company_id_列を含める必要がありますか?または、現在の会社は使用されているスキーマによって暗示されていますか?会社と関係のあるすべてのテーブルで_company_id_を使用するのはやり過ぎですか?

意見1

最初の意見は、会社と他のテーブルとの関係は、テーブル構造で明示的に定義する必要があるというものです。これにより、current_company.projects.find(3)のようなActiveRecordクエリも有効になります。スキーマの境界を越えるリレーションに対しても、参照整合性が適用されます。

意見2

セカンドオピニオンは、テナントスキーマに切り替えると他社からデータを取得できなくなるため、すべてのテーブルのすべての_company_id_列を削除することをお勧めします。同じActiveRecordクエリをProject.find(3)として記述する必要があります。会社は、関係ではなく、選択されたスキーマによって暗示されます。また、すべてのテーブルから_company_id_列を削除すると、ディスク領域を節約できます。

どのアプローチが最適だと思いますか?

2
zwippie

Postgresqlのスキーマは、たとえばMySQLの「データベース」に似ています。これは、データベースオブジェクト(テーブル、ビュー、ストアドプロシージャ、トリガーなど)の個別のコレクションを含む名前空間です。テナントごとにスキーマを作成すると、次のことが可能になります。

  • データベース接続を開いたままにして、スキーマを切り替えます。
  • UNIONを使用して複数のテナント間でクエリを実行し、
  • 誰かがIDを変更し、他の会社のデータにアクセスする問題を回避します。

会社ごとにスキーマを作成する場合、各テーブルにcompany_idフィールドは必要ありません。スキーマは必要な分離を提供します。 ActiveRecordクエリはcompany.Projects.find(3)のようになります。ここで、companyはその特定のテナントに対応するスキーマの名前です。

2
Robert Harvey