回答:
ローエンドでは、基本的には「共有データがないと絶対に言えますか」ということになります。mysqlとは異なり、データベースはpostgresqlの絶対的な境界です。SELECT zip_code FROM common.city_zip WHERE city=...
別のデータベースを使用している場合はできません(少なくともなしではできませんdblink
)。
共有データがある場合、postgresqlの「スキーマ」は、mysqlが「データベース」と呼ぶものに似ています。できCREATE SCHEMA clienta; CREATE TABLE clienta.customer (...);
ます。クライアントごとにスキーマを作成し、そのクライアントのユーザーは最初に検索パスにスキーマを持ち、クライアントAのユーザーがclienta
とpublic
スキーマ(およびそのテーブル)にアクセスできるように権限が付与されます。
問題は、クライアント数の上限では、各テーブルがファイルとして保存されるため、クライアントごとに1つのデータベースを使用する場合でも、クライアントごとに1つのスキーマを使用する${client}_customer
場合でも、テーブル名に何かを使用する場合でも、クライアントごとに1つのテーブルしかない場合でも(接続ごとに1つのファイル記述子)、たとえ10kのクライアントでファイル記述子の制限に達する可能性があります。もちろん、カーネルのファイル記述子の最大数をsysctlを使用してオンザフライで調整できますが、プロセスごとの制限(ulimit)を最初に低く設定しすぎると、postgresqlを再起動する必要があります。
別の方法は、行がどのクライアントに属しているかを識別するクライアント列を持つ「1つの大きなテーブル」を作成することです(理想的には、クライアントごとに1人のユーザーがいる場合はユーザー名によって、これによりLOTの下のものが簡単になります)。クライアントによるこのテーブルへのアクセスをまったく許可しないことにより、クライアント固有のビューを作成できます(またはsession_user
現在のクライアントを識別するために使用できます)。ただし、ビューから直接更新を行うことはできません。テーブルへの挿入/更新/削除の権限を持つ特別なユーザーとして実行するためにsession_user
使用SECURITY DEFINER
する関数を使用して、テーブルへの挿入/更新/削除(クライアントごとに1セットの関数またはを使用する関数)を定義する関数が必要です(注:session_user
使用されているためuser
とcurrent_user
現在のコンテキストに基づいており、SECURITY DEFINER関数内では、これは常に関数を定義したユーザーになります。
パフォーマンスの点では、fdの問題を超えて、10000個のクライアントに相当するデータを含む1つの大きなテーブルがあるのに対して、postgresqlの10000個のデータベースで何が起こるかを正直に知りません。適切なインデックス設計は、大きなテーブルのクエリが遅くなることを防ぎます。
ここでは、クライアントごとに個別のデータベースを使用したと言います(システムを使用可能な状態に保つためにサーバーを追加し、必要に応じてクライアントデータベースを新しいサーバーに移動するため、1つのサーバーで10kデータベースに到達することはありません)。デバッグや定期的なユーザーエラーのために、バックアップから個々のクライアントのデータを復元する必要がありました。これは、「1つの大きなテーブル」の設計では絶対的な悪夢となるものです。また、製品のカスタマイズをクライアントに販売しようとする場合、「1つの大きなテーブル」の設計では、データモデルをカスタマイズする機能にまで踏み込んでしまう可能性があります。
pg_dump -n
スキーマをリストするために(必ず共通スキーマもダンプしてください!)を使用して、一度に1つのクライアントスキーマをダンプできます。psql -E
次に\dn
アプリケーションの詳細がなければ、この設定から追加のセキュリティが得られるとは言いがたいです。各クライアントがWebアプリに接続し、Webアプリからデータベースへの共有ユーザーがいる場合、単一のモノリシックデータベースを使用する場合とは異なる方法でデータを分離していません。適切にパラメーター化されたストアドプロシージャを介してデータにアクセスすると、任意の数のサーバーで10,000以上のデータベースを管理するという管理上の問題なしに、探しているレベルの分離が提供されます。
個人的には、データベース化された単一のデータベースにパラメーター化されたストアドプロシージャを使用して、同様のセットアップを単一のデータベースサーバーで実行しました。データベースへの唯一のアクセスがストアドプロシージャを介したものであることを保証できれば、結果にデータが混在する危険はありません。
デザインを進めたい場合は、主に次の点に注意してください。
ulimit -n
ホストOS で開いているファイル記述子が不足している()SELECT * WHERE clientId = 3
、セキュリティリークがあります。