SaaS Client
、Recruiter
、Panellist
、Owner
など。ユーザーのタイプが増える可能性もあります。
Owner
にはOrganization
があり、これが私のテナントになります。ここでは、すべての所有者の組織をテナントとして検討しています。私はDjangoを使用してこのアプリケーションを開発しており、PostgreSQLで提供されるスキーマ機能を利用するため、schemaすべてのテナント。
私が計画していることは、publicスキーマに保持され、一般的なストアを保持するグローバルUser
テーブルがあることです。姓、名、電子メール、パスワードなどのユーザー情報。User
テーブルは、サイトへのログインに使用されます。また、それぞれのユーザータイプごとに追加のテーブルがあり、それぞれに固有の列のセットがあります。これらの追加のテーブルは、テナント/組織に固有です。
ユーザーがサイトにログインすると、Slackでのワークスペースの機能と同様の目的のテナント/組織に切り替えることができます。テナント/組織内で、ユーザーはOwner
によってユーザーに割り当てられた上記のユーザータイプの役割を引き受けることができます。したがって、ユーザーは1つのテナントのRecruiter
になることができ、別のテナントのPanellist
になることもできます。
UserOrganization
ジャンクションテーブルがあり、User
が複数のOrganization
に属することができるという事実を追跡します。
これが私が考えていることのスキーマ図です:
[〜#〜]ノート[〜#〜]:2番目のテナントのテーブルにスキーマ接続を確立しませんでした。乱雑ですが、すべての意図と目的のために、それらがそこにあると想定しています。
私の質問は:
マルチテナントシナリオで複数のユーザーを扱うときのベストプラクティスは何ですか?
私のデザインの欠点は何ですか?
複数のスキーマを使用してマルチテナントシナリオを実装することは、テナントが少ない場合に実行可能なソリューションです。テナントが多すぎると、テーブルが多くなりすぎて、人生がかなり苦痛になります。
多くのテナントがある場合、すべてのテナントに対して1つのテーブルを使用し、tenant_id
のような列を使用してそれらを識別できます。アプリケーションロジックを信頼してクエリ結果を適切なテナントに制限したくない場合は、 行レベルのセキュリティ を使用して、データベースに任せることができます。
「単一テーブル」アプローチのもう1つの便利なツールは、パーティショニングです。リストパーティショニングを使用して、テナントに基づいてパーティションにその大きなテーブルを分割できます。これにより、複数の(小さい)テナントを1つのパーティションにバンドルできます。パーティション分割により、単一のテナントのすべてのデータを簡単に削除できるようになり(これがその主な利点です)、tenant_id
のインデックスを節約できます。ただし、ほとんどのクエリは、パーティショニングによって高速になりません。