PostGres 上に構築されたマルチテナント EAV システムを Cassandra に移行するかどうかを評価している最中であり、Cassandra でのテストが理にかなっているのかどうかを確認するために、スキーマ アプローチに関する意見を求めていました。私たちのマルチテナント システム階層は、1 つのアカウントで複数のアプリを実行できる account->app で構成されています。クエリは、アプリまたはアカウントごとに分離する必要があります (アカウントのすべてのアプリ データを集計します)。アカウントは、EAV モデルで独自のカスタム フィールドを使用して独自のデータ オブジェクトを作成できます。
私が Cassandra で検討したアプローチは 2 つあります。1 つ目は、1 つの列ファミリー内に特定の数 (たとえば 20) のアプリを保持することです (使用される列ファミリーの数を減らすため)。各行は、accountid->appid->dataobjectid->recordid の複合列によって識別されます。アプリの必要に応じて、アプリの dataobject ごとに列がその場で追加されます。これは、列ファミリーに 2 つのアプリがある場合、最初のアプリの 1 行に 20 列が定義され、2 番目のアプリに 30 列が定義される可能性があることを意味します。これは、これら 2 つのアプリに対して合計 50 の潜在的な列があることを意味します。現在、アプリの列の平均数は 19 です。これは、列ファミリーの列の平均数が 400 になることを意味します。合理的で、Cassandra の幅広い列サポートを利用しています。実際には、おそらく、列ファミリーごとにより多くのアプリを簡単にサポートできます。欠点は、ユーザーが独自のインデックスを作成することを許可していないため、セカンダリ インデックスを作成するのが難しいことです。
2 番目のアプローチは、たとえば 1000 個のアプリのすべてのデータを保持するために 2 つの列ファミリを用意することです。最初の列ファミリには、上記と同じ複合列がありますが、JSON ドキュメント内のその行のデータ オブジェクト全体が保持されます。2 番目の列ファミリーは同じ複合キーを持ちますが、json ドキュメント内のフィールドを表す fieldid という別の値をキーに追加します (アプリのメタデータ マネージャーは、JSON ドキュメント内の各「フィールド」を識別するために UUID を保存します)。文字列、数値、10 進数、浮動小数点数 (日付とブール値は数値に変換されます) の各データ型の「fieldvalue」列があります。ここでの優れた機能は、検索目的でこれらの各列に簡単にインデックスを付けることができ、作成する列ファミリーの数を最小限に抑えられることです。
上記の2つのアプローチの長所と短所は何ですか? 上記のシナリオで、Cassandra に関する明白なまたは誤解を欠いているものはありますか (たとえば、そもそも非常に幅の広い複合列を使用できますか?)。このタイプのアプリのための他のより良いスキーマの提案はありますか?