65

私は、会社のワークフローとプロジェクト管理を容易にすることを目的とした PHP アプリケーションに取り組んでいます。たとえば、 BasecampGoPlanなどです。

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

考えられる短所 1 つのデータベースを使用して考えることができます。

  • 拡張性の欠如
  • セキュリティの問題 (そもそもバグがあるべきではありませんが)

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

4

9 に答える 9

37

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

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

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

于 2008-11-01T08:21:14.380 に答える
36

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

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

于 2008-11-01T16:19:48.640 に答える
24

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

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

(たとえば、「データベース」と「サーバーインスタンス」を構成するものについて、異なるDBMS間で大きな違いがあるため、「インフラストラクチャ」の部分は口当たりが悪いです。 追加:質問には「mysql」というタグが付けられているので、おそらくそれらの考えはありません。完全に関連しているわけではありません。)

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

明らかに、StackOverflow(例として)にはユーザーごとに個別のデータベースがありません。私たちは皆同じデータベースを使用しています。しかし、異なる会社の会計システムを実行している場合、データベースを共有することは(会社にとって、そしておそらく法務担当者にとっては)受け入れられないと思います。

于 2008-11-01T15:58:39.150 に答える
15
  • 開発 迅速な開発のために、顧客ごとにデータベースを使用します。顧客のデータのバックアップ、復元、または削除がどれほど簡単になるか考えてみてください。または、使用状況を測定/監視/請求します。自分でコードを書く必要はありません。データベース プリミティブを使用するだけです。

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

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

于 2009-02-15T12:54:20.827 に答える
11

マルチテナンシーの場合、通常、テナント間で共有するために管理するリソースが増えるほど、パフォーマンスが向上します。

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

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

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

于 2008-11-01T08:04:28.000 に答える
5

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

于 2008-11-01T20:52:06.267 に答える
4

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

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

さらに、マルチテナント アプリケーションを「シャーディング」することは、アプリケーションがますます大きくなるにつれて、最終的に行うべき正しいことになる可能性があります。

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

€ 保証できません。

于 2008-11-01T21:07:59.120 に答える
0

単一のデータベースから始めて、アプリケーションの成長に合わせて分割できます。これを行う場合、私が推奨するいくつかのことがあります。

1) 簡単にパーティション分割できるようにデータベースを設計します。たとえば、顧客がデータを共有する場合は、データが各データベース間で簡単にレプリケートされるようにします。

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

于 2009-01-02T23:15:17.223 に答える