マルチクライアントアプリケーションに単一または複数のデータベースセットアップを使用する必要がありますか?

StackOverflow https://stackoverflow.com/questions/255616

質問

会社のワークフローとプロジェクト管理を容易にするためのPHPアプリケーションに取り組んでいます。 Basecamp および GoPlan

データベースごとの最適なアプローチについてはわかりません。単一のデータベースを使用して、各テーブルにクライアント固有の列を追加する必要がありますか、それとも新しいクライアントごとにデータベースを作成する必要がありますか?重要な要素は自動化です。新しいクライアントを簡単に作成できるようにします(そして、おそらく自分でサインアップする可能性を開きます)。

1つのデータベースを使用することで考えられる短所:

  • 拡張性の欠如
  • セキュリティの問題(バグはそもそも存在しないはずです)

これについてどう思いますか?上記の企業がどのソリューションを選択する可能性が最も高いかについて、アイデアはありますか?

役に立ちましたか?

解決

通常、すべてのテーブルにClientIDを追加し、1つのデータベースを使用します。 しかし、データベースは通常スケーリングが難しいため、一部またはすべてのクライアントの異なるデータベースインスタンスで実行できるようにします。

これにより、1つのデータベースに多数の小さなクライアントを配置し、別のサーバーに大きなクライアントを配置できます。

ただし、保守性の重要な要素は、すべてのデータベースでスキーマを同一に保つことです。クライアント固有のスキーマを導入せずにバージョン管理を管理するのに十分な頭痛の種があります。

他のヒント

JoelとJeffが同じ質問について話しているStackoverflowポッドキャストを聞いてください。 Joelは、ホストされたバージョンのソフトウェアを提供した経験について語っています。 DB全体にクライアントIDを追加すると、デザインとコードが複雑になり(WHERE句に誤って追加するのを忘れなかったのですか?)、クライアント固有のバックアップなどのホスティング機能が複雑になると彼は指摘します。

エピソード#20または#21でした(詳細についてはトランスクリプトを確認してください)。

私の見解では、それはあなたの見込み客ベースに依存します。アーチライバルが両方ともシステムを使用している状況に陥る可能性がある場合は、個別のデータベースを使用する方が良いでしょう。また、DBMSが複数のデータベースを実装する方法にも依存します。各データベースにインフラストラクチャの個別のコピーがある場合、それは単一のデータベース(またはDBMSの変更)を示唆しています。インフラストラクチャの単一のコピーで複数のデータベースを提供できる場合は、個別のデータベースを使用します。

データベースのバックアップを考えてください。顧客Aは「データのコピーを送ってください」と言います。単一のデータベースを共有する場合よりも、個別のデータベース設定ではるかに簡単です。顧客を削除することを考えてください。繰り返しますが、個別のデータベースを使用するとはるかに簡単です。

(たとえば、「データベース」と「サーバーインスタンス」を構成するものに関してDBMSによって大きな違いがあるため、「インフラストラクチャ」の部分は非常に口が広いです。追加:質問は「mysql」とタグ付けされているため、これらの考えは完全には関連していない可能性があります。)

追加: もう1つの問題-単一のデータベースに複数の顧客がいる場合、すべてのSQLクエリで正しい顧客のデータが選択されるようにする必要があります。これは、SQLの書き込みと読み取りが難しくなり、DBMSのデータ処理が難しくなり、インデックスが大きくなることを意味します。多くの目的のための顧客。

明らかに、StackOverflow(例として)にはユーザーごとに個別のデータベースはありません。すべて同じデータベースを使用しています。しかし、異なる企業の会計システムを運用している場合、データベースを共有することは(企業にとっては、場合によっては法人にとっては)許容できないと思います。

  • 開発 迅速な開発のために、顧客ごとにデータベースを使用します。顧客のデータのバックアップ、復元、削除がどれほど簡単になるかを考えてください。または、使用量を測定/監視/請求します。自分でコードを作成する必要はなく、データベースプリミティブを使用するだけです。

  • パフォーマンス パフォーマンスのために、すべてにデータベースを使用します。接続プーリング、共有メモリ、キャッシュなどについて考えてください。

  • ビジネス あなたのビジネスプランが多くの小規模な顧客を抱えている場合(hotmailを考えてください)、おそらく単一のDBで作業する必要があります。また、登録、削除、データ移行などのすべての管理タスクを完全に自動化し、使いやすいインターフェイスで公開します。数十または最大数百の大規模な顧客を抱える場合、顧客ごとに1つのDBで作業し、顧客サポートスタッフが操作できるシステム管理スクリプトを用意できます。

次のスクリーンキャストでは、salesforce.comでの実行方法について説明しています。各テナントのデータを識別する特別な列OrgIdを持つ1つのデータベースを使用します。それにはもっと多くのことがあるので、これを調べる必要があります。私は彼らのアプローチに行きます。

MSDNには、別の優れた記事があります。共有アプローチまたは分離アプローチを使用する必要がある場合について詳しく説明します。 すべてのテナントに共有DBを持たせることには、いくつかの重要なセキュリティの意味があり、それらすべてが同じDBオブジェクトを共有する場合は、使用するDBMSに応じて[行レベルセキュリティ]を使用できます(MS SQL ServerとOracle、おそらくIBM DB2にもあります)。 mySQLの行レベルセキュリティのようなトリックを使用して、同様の結果(ビュー+トリガー)を実現できます。 )。

マルチテナンシーの場合、パフォーマンスは通常、テナント間で共有するために管理するリソースが増えるほど増加します。を参照してください

http://en.wikipedia.org/wiki/Multitenancy

したがって、可能であれば、単一のデータベースを使用してください。アプリケーションにすべてのアクセス制御を実装できるため、セキュリティの問題はバグが原因でのみ発生することに同意します。一部のデータベースでは、ビューを慎重に使用することでデータベースのアクセス制御を引き続き使用できます(したがって、認証された各ユーザーは異なるビューを取得できます)。

拡張性を提供する方法もあります。たとえば、拡張属性(テナント、ベースレコード、および拡張属性IDをキーとする)を持つ単一のテーブルを作成できます。または、テナントごとの拡張テーブルを作成して、各テナントに独自の拡張スキーマを持たせることもできます。

マルチテナントデータベースを設計する場合、一般的に3つのオプションがあります。

  1. テナントごとにデータベースを1つ持つ
  2. テナントごとにスキーマを1つ持つ
  3. すべてのテナントが同じテーブルを共有する

選択するオプションは、スケーラビリティ、拡張性、および分離に影響します。これらの影響は、さまざまな StackOverflowの質問とデータベースの記事で広く議論されています。

実際には、3つの設計オプションのそれぞれが-十分な労力で-規模、テナントによって異なるデータ、および分離に関する問題に対処できます。決定は、構築するプライマリディメンションによって異なります。概要:

  • 規模を拡大する場合:すべてのテナントが同じテーブルを共有する
  • 分離のために構築する場合:テナントごとに1つのデータベースを作成します

たとえば、 Google とSalesforceは最初のパターンに従い、テナントが同じテーブルを共有するようにします。一方、Stackoverflowは2番目のパターンに従い、テナントごとに1つのデータベースを保持します。 2番目のアプローチは、ヘルスケアなどの規制産業でも一般的です。

決定は、データベース設計を最適化する主要な次元に委ねられます。 あなたのデザインに関するこの記事SaaSデータベースfor scale はトレードオフについて説明し、PostgreSQLのコンテキストで要約を提供します。

考慮すべきもう1つの点は、ある会社のデータを別の会社のデータとは別に保管する法的義務がある場合があることです。

クライアントごとにデータベースを保持することは、通常、うまく拡張できません。 MySQL(およびおそらく他のデータベース)は、テーブルごとにリソースを開いたままにします。これは、1つのインスタンスで10,000を超えるテーブルには適していません。これは、大規模マルチテナンシーの状況で発生します。

もちろん、このレベルに到達する前に他の問題を引き起こす他の問題がある場合、これは関係ないかもしれません。

さらに、「シャーディング」マルチテナントアプリケーションの可能性があります€アプリケーションがどんどん大きくなったときに最終的に正しいことになるように。

ただし、シャーディングとは、テナントごとに1つのデータベース(またはインスタンス)を意味するのではなく、シャードまたはシャードのセットごとに1つ(それぞれが複数のテナントを持つ可能性がある)を意味します。おそらく本番環境で、適切なチューニングパラメータを見つける必要があります(そのため、最初からかなり調整可能である必要があります)

€保証できません。

単一のデータベースから開始し、アプリケーションの成長に応じてパーティション化できます。これを行う場合、いくつかのことをお勧めします:

1)簡単に分割できるようにデータベースを設計します。たとえば、顧客がデータを共有する場合、データが各データベース間で簡単に複製されることを確認してください。

2)データベースが1つしかない場合は、データベースが別の物理サーバーにバックアップされていることを確認してください。フェイルオーバーが発生した場合、トラフィックをこの他のサーバーに戻すことができ、データをそのまま保持できます。

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top