登録ユーザー(実際には会社)を他のユーザーから分離する必要があるアーキテクチャを持つWebアプリケーションがあります。つまり、同じWebアプリケーションを同じデータモデルで実行しますが、顧客ごとに異なるデータセットを使用します。
したがって、私たちはPostgresで顧客ごとに異なるデータベースを作成することを考えました。このソリューションは、たとえば10〜20Kのデータベースに拡張できますか?いかに良く?
誰かがこれのためのより良い解決策を持っていますか?
前もって感謝します。
ローエンドでは、基本的には「共有データがないと絶対に言えますか」ということになります。 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
を使用する関数を使用して、テーブルの挿入/更新/削除(クライアントごとに1セットの関数またはSECURITY DEFINER
を使用する関数)を定義する関数が必要です。 (注:user
およびsession_user
は現在のコンテキストに基づいており、SECURITY DEFINER関数内では常にこれが関数を定義したユーザーになるため、current_user
が使用されます)。
パフォーマンスの点では、fdの問題を超えて、10000個のクライアントに相当するデータを含む1つの大きなテーブルがあるのに対して、postgresqlの10000個のデータベースで何が起こるかを正直に知りません。適切なインデックスの設計により、大きなテーブルのクエリが遅くならないようにする必要があります。
ここでは、クライアントごとに個別のデータベースを使用したと言います(システムを使用可能な状態に保つためにサーバーを追加し、必要に応じてクライアントデータベースを新しいサーバーに移動するため、1つのサーバーで10kデータベースに到達することはありません)。デバッグのために、または定期的にユーザーエラーのために、バックアップから個々のクライアントのデータを復元する必要がありました。これは、「1つの大きなテーブル」の設計では絶対的な悪夢となるものです。また、製品のカスタマイズをクライアントに販売しようとする場合、「1つの大きなテーブル」の設計では、データモデルをカスタマイズする機能まで行き詰まる可能性があります。
アプリケーションの詳細がなければ、このセットアップでセキュリティを強化できるとは言いがたいです。各クライアントがWebアプリに接続し、Webアプリからデータベースへの共有ユーザーがいる場合、単一のモノリシックデータベースを使用する場合とは異なる方法でデータを分離していません。適切にパラメーター化されたストアドプロシージャを介してデータにアクセスすることで、任意の数のサーバーで10,000以上のデータベースを管理するという管理上の問題なしに、探しているレベルの分離を実現できます。
個人的には、単一のデータベースにアクセスするパラメーター化されたストアドプロシージャのみを使用して、単一のデータベースサーバーで同様のセットアップを実行しました。データベースへの唯一のアクセスがストアドプロシージャを介したものであることを保証できれば、結果にデータが混在する危険はありません。
デザインを進めたい場合は、主に次の点に注意してください。
ulimit -n
)ホストOS