現在、単一のエンドカスタマーが使用するアプリケーションがあります。議論を簡単にするために、アプリケーションはすべてのレコードに対して単一のデータベーステーブルのみを必要とすると仮定します。今はマルチテナンシーをサポートする必要があるので、将来的には同じデータベースサーバーを使用する約500人の顧客がいます。
1)可能な解決策は、顧客ごとに個別のデータベースを用意することです。 MySQL/SQL Server/Oracle/etcを持っていることを意味する約500の顧客がいるので... 500の個別のデータベースをホストします。これは、平均的なクラウドベースのサーバーで実行されているデータベースサーバーにとってはやり過ぎのように思えます。
2)別の解決策は、私がすでに持っている単一のデータベースを使い続けることですが、各エンドカスタマーに1つずつ、500の異なるテーブルを用意する必要があります。各顧客の平均は、自分のテーブルで約2000レコードだけです。これは実装が簡単で、顧客を別のサーバーに簡単に移行できます。テーブル全体のデータを移動するだけです。
3)最後に、単一のデータベースで単一のテーブルを使用することに固執することができました。代わりに、レコードが属する顧客を識別する追加の列を追加します。しかし、テーブルは最終的に約1,000,000のレコードで終わります。これは、平均2,000の500の顧客すべての合計です。
1、2、3が最高のパフォーマンスを提供することを知るには、パフォーマンスとスケーリングについて十分に知りません。何か案は?
個人的には、次の理由でオプション3を選択します。
また、パフォーマンスはさておき、ここにオプション1と2を避けたい理由がいくつかあります。
顧客ごとに1つ、500のデータベースを使用する場合の欠点:
1つのデータベースに500テーブル、顧客ごとに1つのテーブルを使用する場合の短所:
マルチテナンシーを検討するときは、パフォーマンスだけでなく、評価する必要があります。詳細については、こちらをお読みになることをお勧めします このMSDNの記事 。
大まかに言えば、特定のアプローチを決定する前に、これらの要因を考慮する必要があります。
そして、あなたが指摘したように、考慮すべき本質的に3つのアプローチがあります:
そして、長所と短所の簡単な要約:
全体的にコストは高くなりますが、コードがシンプルになり、セキュリティ面での検証が容易になります。クライアントのデータ使用量が増加したときに特定の環境をアップグレードするのは簡単です。
専用のデータベースアプローチと比較してコストは削減されますが、コードの複雑さが増すというトレードオフがあります。そして、スキーマが分離されたままであることを確認するには、より勤勉である必要があります。場合によっては、クライアントごとにコピー/貼り付けを行う必要があるため、繰り返しの多いコードが含まれる可能性があります。繰り返しますが、データの使用がアップグレードを正当化するものであれば、クライアントを移行するのは比較的簡単です。
また、コストも削減されましたが、安全性を維持するためにコードの複雑さが増しています。セキュリティアクセス層でミスをすると、不注意によるデータ漏洩のリスクが高くなります。一方で、スキーマ間で複製を行わないため、コードの繰り返しが少なくなります。欠点は、クライアントのデータ使用量が既存の環境の能力を超える場合、このアプローチには最も複雑な移行パスがあることです。
2番目の2つのアプローチは、コストの削減のために、私が最もよく使用する方法です。
クライアントのデータ使用方法が大きく異なる組織では、2番目のアプローチを使用する傾向があります。
一貫性がありデータ使用量が少ない組織は、3番目に傾いています。
私見マルチテナンシーを念頭に置いて新しいアプリケーションを最初から設計する場合、またはマルチテナンシー用に設計されていない複雑な既存のアプリケーションを使用する場合は、違いが生じます。
最初の状況では、他の人が書いたように、「1つのDBと1つのテーブル」のアプローチがおそらく最良です。もう1つは、後でアプリケーションにマルチテナンシーを追加するのが非常に難しくなるため、アプリケーションで何かを変更する必要がなくなるため、異なるデータベースを使用するほうが良い代替案になる可能性があります。もちろん、「異なるデータベース」は、MS SQLサーバーシステムやMySQLサーバーと比較して、Oracleシステムを使用する場合のオーバーヘッドが異なります。 Oracleシステムには、「異なるスキーマ」のオプションもあり、Oracle 12cからは、特定の「マルチテナント」オプションがあり、多数の「プラグ可能なデータベース」を保持するコンテナーDBを作成できます。
実際にテーブルが1つしかない限り、アプリケーションはそれほど複雑ではなく、後でマルチテナンシーを実装できないと思いますが、
議論を簡単にするために、アプリケーションはすべてのレコードに対して単一のデータベーステーブルのみを必要とすると仮定します。
実際のテーブルにはもっと多くのテーブルがあると思います。アプリケーションに関連する変更を加えるのがどれほど難しいかを判断する必要があります。
その一部は個人の好みによるものだと思います。
同じアプリケーションで複数の顧客を処理する場合(つまり、1つのプログラムが複数の顧客からの要求を受信する場合)、オプション3を使用します。この場合の複数の顧客の処理は、アプリケーションロジックの一部であり、データモデルに組み込まれています。
顧客ごとにアプリケーションの個別のインスタンスを実行する場合、私は最初にオプション1を選択する傾向があります。これは、顧客間の分離が最も優れているためです。
ただし、数百の顧客がいる場合、オプション1は適切にスケーリングされないためかなり扱いにくくなり、オプション2は適切な妥協案です。
1番が最高のパフォーマンス、3番が最悪です。しかし、実際には、他の多くの回答が述べているように、これは、特に質問に投稿したデータの量に関して、あなたが心配する必要がある最後のことです。
私が気になるもの:
これらのそれぞれを拡張するには:
これがyourデータの場合、これは問題にはなりません。ただし、これがクライアントの企業データ、またはあらゆる種類の個人データ、または絶対に漏洩してはならないデータである場合-3番は問題外です。何らかの魔法でrowsのサブセットのみを読み取れないようにしない限り、任意のクライアントが他のクライアントデータにアクセスすることを許可します。あなたの顧客はこれを感謝しないかもしれません。実際、ターゲットがジューシーである場合、実行時間またはテーブルの統計(行数など)はすでに、公開したい情報よりも多くの情報を提供しています。
許可とユーザーが適切である限り、2番目は問題ありません。
この質問への答えは-もちろん、遅かれ早かれあります。すべてを配置するDBにテキストフィールドが1つしかない場合を除きます。
スキーマを適切に変更する方法があります。コードの新しいバージョンが古いスキーマバージョンと新しいスキーマバージョンの両方で機能すること、またはその逆であることを確認してください。また、すべてのクライアントがタイムリーに更新されていることを確認する必要もあります。ただし、これは、クライアントを強制的に更新するか、スキーマの変更を2つの主要な更新にまたがる必要があることも意味します。
上記はどのようにあなたの状況に関係していますか?さて、3番目に、すべてのクライアントのすべての更新を同期する必要があります。それは控えめに言っても悪夢です。数値1と2は、問題のあるクライアントを1つずつオフにせずに実行できるため、この意味でより簡単です。
3番目のクライアントは、クライアントの1つが古いバージョンのアプリを要求した場合にも新しいものではないため、地獄です。
最初に思い浮かぶのはバックアップです。ここでオプション3はすべてを際立たせます-テーブルをダンプするだけで完了です! 2番目は問題ありません-完全なDBバックアップはそれほど難しくありません。番号1は悪いです-各DBにバックアップをセットアップする必要があります。何かを忘れたりファッジしたりするのは信じられないほど簡単です。ただし、クライアントにリクエストに応じてtheirデータのバックアップを提供することは、1と2では簡単ですが、3には少し関係します。
どのくらいの頻度でクエリをDBに変更する必要がありますか? 3番目の場合、それらはもっと複雑になります-むしろ-それらは同じくらい単純ですが、AND clientId = :clientId
。
1の場合は、優れた開発者チームとエンタープライズサーバーがあることを望みます。これを行う方法は簡単で、信頼性が高く、費用対効果が高くありません。
2番目のクエリは、クエリを適切に生成できる限り問題ありません。
3番が一番簡単です。
質問がある場合は、分析部門に質問する必要があります。
多くのDBには、多くのライセンスが必要になる場合があります。そして、たくさんの開いているポート、そしておそらく仮想マシン。これは、正確に何を使用しているか、どのホスティングであるかによって異なります。
物理的にをどこに置くことができるかについての法的要件が時々あります。すべてのクライアントが1つの国から来ているのであれば問題はないはずですが、世界中に行っても問題ないでしょう。これは特に財務データと個人データに当てはまります。
ここで言及されていない質問-DBのレイテンシに関する要件はありますか?オーストラリアやロシアのクライアントは、クエリがニューヨークに行くことに満足していないかもしれません(たとえば)。
もう1つは、回復力とDDoSです。個別のクライアントに対して物理的に分離されたサービスは、削除するのがはるかに困難です。
全体として、これを小規模なストレージとして主に非独占的で重要でないデータに使用していて、(会社の成長ではなく、データの量のように)大きな成長やフォーマットの変更を期待していない場合、 -番号3を使用します。面倒が少なく、コストが低く、管理者が少なくて済みます。これが適切なデータストアに成長し、中には非常に扱いにくいものが含まれる場合-番号1を使用します。番号2はその中間にあります。
3つすべて使用します。 1つのサイズですべてに対応できるわけではありません。
共有モデル/共有サーバーは、小規模な実装や、最小限のデータセキュリティが必要な顧客に使用できます。たぶん、これにはアプリケーションの仕組みが必要です。
費用:$
排他的なモデル/共有サーバーにより、データの分離が向上しますが、クライアントは同じリソース(サーバー)を共有します。
費用:$$$
専用モデル/専用モデルにより、独自のサイロを実現。
費用:$$$$$
このモデルを使用すると、クライアントは自分に合った最適なモデルを選択できます(サイズとセキュリティ上の問題による)。収益性を維持するために、それぞれにいくら充電するかを把握する必要があるだけです。
すべてが同じ、オプション#3-すべてが1つのテーブル(またはテーブルのセット)にあります。
提供されている他のいくつかの理由に加えて-メンテナンスが容易で、パフォーマンスが適切にインデックス付けされていれば、パフォーマンスに大きな違いはないはずです-将来のプルーフの問題もあります。
データの移行を検討してください。オプション3を使用する場合、将来、本当に必要な場合は、1または2に移行するのは簡単です。たとえば、顧客が独自のデータベースを必要とするような大幅なカスタマイズが必要になった場合。 IDをすべて同じに保ちながら、データを新しいテーブルに移動するだけです。一方、データを共有する必要がある理由を発見した場合、1または2からオプション3に移行するのは非常に困難です。結合するよりもデータを分割する方が常に簡単です。