読み取りパフォーマンスを大幅に改善することを目標に、社内で CQRS システムの読み取り部分を実装しようとしています。現在、読み取りは、SQL Azure データベースからのある程度の逆シリアル化を含む、正規化されたデータに対して Linq-to-SQL クエリを実行する Web サービスを介して行われます。
データの単純化された構造は次のとおりです。
- ユーザー
- 会話 (同じ受信者へのメッセージのグループ化)
- メッセージ
- 受信者 (ユーザーのセット)
これを非正規化状態に移動して、ユーザーがメッセージのフィードを表示するように要求したときに、次のいずれかから読み取るようにします。
Azure Table Storage に保持される非正規化表現
- PartitionKey としての UserID
- RowKey としての ConversationID
- エンティティとして保存された、変更されやすい揮発性データ
- エンティティで JSON としてシリアル化されたメッセージ
- エンティティで JSON としてシリアル化されたメッセージの受信者
- これに関する主な問題は、Table Storage (960KB) の行のサイズが制限されていることです。
- また、「揮発性データ」列に対するクエリは、キーの一部ではないため遅くなります。
Azure Table Storage に保持されている正規化された表現
- 会話の詳細、メッセージ、受信者の別の表
- Conversation テーブルに格納されているメッセージと受信者のパーティション キー。
- それを禁止します。これは上記と同じ構造に従います
- 最大行サイズの問題を回避します
- しかし、正規化された状態は、非正規化されたテーブルのパフォーマンスの向上を低下させますか?
また
SQL Azure で保持される非正規化表現
- 複合主キーとして保持される UserID & ConversationID
- 別の列に格納された、変更されやすい揮発性データ
- 列に JSON としてシリアル化されたメッセージ
- 列に JSON としてシリアル化されたメッセージの受信者
- 非正規化データの索引付けと構造に対する最大の柔軟性
- Table Storage クエリよりもはるかに遅いパフォーマンス
私が尋ねているのは、Table Storage または SQL Azure で非正規化構造を実装した経験がある人がいるかどうかです。どちらを選びますか? または、私が見逃したより良いアプローチはありますか?
私の直感では、Table Storage の正規化された (少なくともある程度) データが適していると思います。ただし、ユーザーのすべてのデータを取得するために 3 つのクエリを実行すると、パフォーマンスの向上が低下するのではないかと心配しています。