3

問題は、SQLServer2012上のSQLについてです。

バックグラウンド:

エンティティと呼ばれるエンティティがあります。

エンティティはNEntityVersion1:n を持つことができます。

EntityVersionは承認される場合とされない場合があります。承認されると、バージョン全体で属性ApprovedByが割り当てられます。

要件:

すべてのエンティティの最新のエンティティバージョンを一覧表示する必要がありますが、各エンティティの最新の承認済みバージョンのみを一覧表示します。

問題:

大規模なソリューションのクエリ全体を実現するための最適な方法を見つける必要があります。

そのため、私は2つの可能なアプローチを考えました。

  1. EntityVersionのIsLastフラグ列。新しいバージョンが追加されるたびに、トランザクション全体がtrue新しく追加されたバージョンに設定され、以前の最後のバージョンに。が割り当てられfalseます。

  2. すべての新しいエンティティバージョンの挿入を処理し、最新バージョンのみを持つ特別なテーブルに新しいバージョンを追加するトリガー。新しいバージョンが追加されるたびに、前のバージョンは特別なテーブル全体から削除されます。つまり、SELECTリスト全体を取得するのは非常に安価です。

質問:

最適で有効なアプローチは何でしょうか?他に何か考えていることはありますか?

ありがとう!

「最適」とは、スケーラブルであり、何百万ものレコードで機能することを意味することに注意してください



アップデート

回答の一部のユーザーがとのスキーマを要求していることがわかったので、EntityそれらEntityVersionをより適切に説明します。

  • エンティティにはテキスト情報はありません。識別子と他のエンティティとの関係だけです。

  • EntityVersionには、テキストおよびその他の情報があります。例:タイトル、説明、作成者...からの重複情報がないことを言及することが重要です。EntityVersionEntity

SELECT DISTINCT最も簡単な解決策は、個別の列を定義し、同じクエリで他の列を選択できるようなものを用意することです。悲しいことに、私が知る限り、これはSQL Serverでは不可能です(私は間違っていますか?)。

4

1 に答える 1

1

IsLast フラグ列で十分だと思いますが…。

  1. 答える必要がある最初の質問は、EntityVersions に対する Entities の比率は? です。これはあなたの決定に影響を与える可能性があります。
  2. また、テーブルの構造についてはわかりませんが、EntityVersion テーブルは、変更されたフィールドを格納する Entity テーブルのコピーであると想定します (または、単に差分をとっただけでしょうか?)。その場合は、最新バージョンを Entity 自体に保存してみませんか。これはより意味的に正しいアプローチだと思います。
  3. 通常、正しいインデックスがあれば (おそらくcolumnstoreIndexesを組み込んでみますか?)、高価な可能性があるトリガーのような特別な作業を実行する必要はありません。GroupBy を使用した通常の Join を使用してテストを実行してみてください (または、EntityVersion テーブルに必要なフィールドがすべて含まれている場合は、結合する必要さえありません)。または、おそらくこのアプローチは少し速くなるでしょう: https://stackoverflow.com/a/438990/1792936
  4. 繰り返しになりますが、実行計画と速度テストに基づいて最適なクエリを作成することしかできません。

  5. 他のすべてが失敗した場合は、CQRS パターンまたは類似のものを組み込んでみてください。

于 2013-03-10T21:16:19.997 に答える