私は現在、システムのコア機能としてユーザーがカスタムタイプを定義できるマルチテナントシステムを開発しています。したがって、たとえば、イベント、アカウント、注文、出荷を選択して定義します。システム内のすべてのユーザーは、フィールドに関して管理したいものに対して異なる定義を持ちます。したがって、あるユーザーの場合、注文には注文番号、ステータス、期日があり、別のユーザーの場合は10個のフィールドがあります。
私が協力している開発者は、EAVを使用してこのデータを保存したいと考えています。私はこの考えに反対です。私はこのサイトやインターネット全体でこのアンチデザインパターンの欠点をリストした多くの記事を読みましたが、私がとろうと考えているアプローチについては言及していません。このアプリケーションは、最初からスケーラブルになるように構築しようとしています。
私が計算をするとき、私が1000のテナントを持っている場合、それぞれ平均5つのタイプ(5000のタイプ)があります。たとえば、各タイプには1000レコード(5,000,000レコード)があります。各レコードには平均5つのフィールドがあり、EAVモデルの最下位レベルで合計25,000,000行になります。
ダウンストリームプロセスでは、個々のユーザーデータをjqueryグリッドにバインドすることもあるため、最初にこのデータをフェッチしてデータを転置することは、私には非常にコストがかかるように思われます。10kのテナントまたは5万のテナントがある場合はどうなりますか...MySQLは最適化されたときにこのタイプのことを処理できることを理解していますが、足を踏み入れているように見えます。
別のやり方でやりたいです。しかし、私が提案していることは、私が知っているすべてのものに反するため、直感が悪いので、実践的な知識を持つ実際の専門家に、私のアプローチを検証または批判してもらいたいと思います。検証する場合は、それをサポートして機能させるために私が何をする必要があるかを教えてください。批判されたら、私が短期的および長期的に直面する落とし穴を教えてください。
わたしの提案。
- 特定のシャードにテナントの最大セットが存在するように、ドメインパーティショニングを使用してシステムをシャードします。マスターカタログは、どのテナントがどのシャードに属しているかを参照します
- シャードごとに、ユーザーがタイプを定義するときに、このタイプを保持するための新しいテーブルを作成します。シャードにマッピングテーブルを保持します。これにより、ユーザーは定義されたタイプ(カスタムテーブル)にリンクされます。
これは基本的に、1つのシャードに少数のコアテーブルと数千のカスタムテーブルがあることを意味します。
私にとって、通常、データベースにその数のテーブルがあると、スキーマに何か問題があるか、何かが正しく設計されていないことがわかりますが、このシナリオでは、それが実行可能なアプローチであるかどうかを知りたいだけです。前の例では、シャードに5000個のテーブルがあり、それぞれが1000行しかないことを意味します。これは、EAVを使用するよりも優れたアプローチのように思えます。ユーザーに基づいて、タイプを見つけ、データをグリッドにバインドします。
考慮すべきいくつかの注意事項
マルチテナントアーキテクチャにより、ユーザーは独自のユーザーを持つことができます。したがって、潜在的に私には1000人のサブスクライバーがいますが、5000人のユーザーがいます。したがって、データベース接続を管理する必要があります。接続の管理で問題が発生しますか?
テーブルキャッシュ関連の問題が発生しますか?テーブルのフラッシュに問題がありますか?
この設計でパフォーマンスの問題が発生する可能性はありますか?マスターカタログデータベースがボトルネックになる可能性があることは理解していますが、このデータベースの負荷はそれほど大きくありません。
開発はすでに始まっています。NoSQLデータベースに変更するように言わないでください。
もう1つの提案は、EAVを引き続き使用することでしたが、シャード内にあります。このアイデアについてどう思いますか?
パンチを引っ張らないでください!私はそれをすべて聞く必要があります。前もって感謝します。