マルチテナント設計に関するPostgreSQLメーリングリストの情報を検索することをお勧めします。そこにはたくさんの議論があり、答えは「状況次第」に要約されます。保証された分離、パフォーマンス、および保守性の間には、あらゆる方法でトレードオフがあります。
一般的なアプローチは単一のデータベースを使用することですが、1つのスキーマ (名前空間)各スキーマで同じテーブル構造を持つ顧客ごとに加えて、すべてのスキーマで同じデータの共有スキーマまたは共通スキーマ。 PostgreSQLスキーマは、異なるスキーマ間でクエリを実行できるという点でMySQLの「データベース」に似ていますが、デフォルトでは分離されています。別のスキーマの顧客データを使用すると、 search_path
設定、通常は ALTER USER
customername SET search_path ='customerschema、sharedschema'
各顧客に自分のデータと自分のデータのみが表示されるようにします。
保護を強化するには、 REVOKE
を実行する必要があります。
ALL FROM SCHEMA Customerschema FROM public
次に、 GRANT
ALL ON SCHEMA Customerschema to thecustomer
したがって、アクセスできるのは彼らだけであり、各テーブルに対して同じことを行います。接続プールは、ない固定ユーザーアカウントでログインできます。 GRANT
edは任意の顧客スキーマにアクセスできますが、役割の設定
どんな顧客にもなります。 (これを行うには、NOINHERITが設定された各顧客の役割のメンバーシップを与えることで、 SET ROLE
を介して権利を明示的に要求する必要があります。 )。接続はすぐにSETROLE
する必要があります 現在運用しているお客様へ。これにより、間違った顧客のデータへのアクセスにつながるプログラマーのエラーに対する強力な保護を維持しながら、顧客ごとに新しい接続を確立するオーバーヘッドを回避できます。プールがすべてを破棄
>
および/または RESET ROLE
次のクライアントに接続を渡す前に、ユーザーごとの個々の接続に不満を感じることなく、非常に強力な分離を実現します。
Webアプリ環境に適切な接続プールが組み込まれていない場合(たとえば、永続的な接続でPHPを使用している場合)、本当に 良好な接続プール
を配置する必要があります バックエンドへの接続が多すぎるとパフォーマンスが低下するため、とにかくPgとWebサーバーの間に配置します。 PgBouncer
および DISCARD ALL
の実行を手軽に行うことができます およびRESETROLE
接続ハンドオフ中にあなたのために。
このアプローチの主な欠点は、非共有テーブルの基本セットが顧客ごとに複製されるため、その数のテーブルを維持することによるオーバーヘッドです。顧客数が増えるにつれて、自動バキュームの実行中に調査するテーブルの数が膨大になり始め、DB内のテーブルの総数に基づいてスケーリングする操作が遅くなるまで、合計されます。同じDBに数千または数万の顧客がいることを考えている場合、これはさらに問題になりますが、私は強く コミットする前に、ダミーデータを使用してこの設計でスケーリングテストを行うことをお勧めします。
理想的なアプローチは、タプルの可視性を制御する自動行レベルのセキュリティを備えた単一のテーブルである可能性がありますが、残念ながら、それはPostgreSQLにはまだありません。適切なインフラストラクチャとAPIを追加するSEPostgreSQLの作業のおかげで進行中のようですが、9.1にはありません。