私たちは、すべての企業が独自のデータベーススキーマを使用するSASSWebアプリケーションを構築しています。 postgresqlを使用すると、パブリックスキーマにテーブル「companies」があり、会社の名前と切り替え先のスキーマの名前が保持されます。テナントスキーマには、この会社に固有のデータを格納するテーブルがたくさんあります。すべてのリクエストで、テナントスキーマは、セッションに保存されている現在の会社に基づいて設定されます。
内部の議論はこれです:
テナントスキーマのテーブルには、データと会社の関係を示す_company_id
_列を含める必要がありますか?または、現在の会社は使用されているスキーマによって暗示されていますか?会社と関係のあるすべてのテーブルで_company_id
_を使用するのはやり過ぎですか?
意見1
最初の意見は、会社と他のテーブルとの関係は、テーブル構造で明示的に定義する必要があるというものです。これにより、current_company.projects.find(3)
のようなActiveRecordクエリも有効になります。スキーマの境界を越えるリレーションに対しても、参照整合性が適用されます。
意見2
セカンドオピニオンは、テナントスキーマに切り替えると他社からデータを取得できなくなるため、すべてのテーブルのすべての_company_id
_列を削除することをお勧めします。同じActiveRecordクエリをProject.find(3)
として記述する必要があります。会社は、関係ではなく、選択されたスキーマによって暗示されます。また、すべてのテーブルから_company_id
_列を削除すると、ディスク領域を節約できます。
どのアプローチが最適だと思いますか?
Postgresqlのスキーマは、たとえばMySQLの「データベース」に似ています。これは、データベースオブジェクト(テーブル、ビュー、ストアドプロシージャ、トリガーなど)の個別のコレクションを含む名前空間です。テナントごとにスキーマを作成すると、次のことが可能になります。
会社ごとにスキーマを作成する場合、各テーブルにcompany_idフィールドは必要ありません。スキーマは必要な分離を提供します。 ActiveRecordクエリはcompany.Projects.find(3)
のようになります。ここで、company
はその特定のテナントに対応するスキーマの名前です。