2

SQL Server を使用して非常に基本的なイベント ソーシングを実装しようとしています。ライブラリも、他のサーバーも、特別なものもありません。SQL Server を使用する基本から始めてください。

次のテーブルがあるとします。

Id | Name      | Data   | CreatedOn
1  | Fruit     | Apple  | <DATE_TIME> Apr 1, 2015
2  | Fruit     | Peach  | <DATE_TIME> Apr 5, 2015 
3  | Fruit     | Mango  | <DATE_TIME> Apr 10, 2015
4  | Vegetable | Potato | <DATE_TIME> May 20, 2015
5  | Vegetable | Tomato | <DATE_TIME> May 30, 2015

結果が次のようになるように、名前でグループ化された最新のデータを表示するビューを作成したいと思います。

Id | Name      | Data   | CreatedOn
3  | Fruit     | Mango  | <DATE_TIME> Apr 10, 2015
4  | Vegetable | Tomato | <DATE_TIME> May 30, 2015

簡単に、CREATE VIEW Latest AS SELECT t1.* FROM table t1 JOIN (SELECT TOP 1 Id FROM table ORDER BY CreatedOn DESC, Id DESC) t2 ON t2.Id = t1.Id;

これで、テーブルに何百万もの行があり、ビューで多数の同時読み取りが行われることになります。それで、インデックスを付けたいと思います(SQL Server Indexed Views)。インデックス付きビューには派生テーブルまたは TOP OR MAX OR 自己結合を含めることができないため、ここでは運が悪いようです。

インデックス付きビューを作成する方法について何か考えはありますか?

それが不可能な場合は、テーブル内の IsLatest BIT 列を更新する INSTEAD OF トリガーを使用し、このフィルターに基づいてインデックス付きビューを作成できます。

他の提案はありますか?

4

1 に答える 1

1

既存のビュー定義はSELECT TOP 1 Id FROM table ORDER BY CreatedOn DESC, Id DESC1 つの行しか返さないため機能しませんが、外側の行ごとに 1 つ必要でした。

このクエリは、インデックス付きビューでは具体化できません。クエリを次のように再定式化しても、次のようになります。

select *
from T t1
join (
 select Name, MAX(ID) as MaxID
 from T
 group by Name
) t2 on t1.name = t2.Name and t1.ID = t2.MaxID

その意味のある部分を具体化することはできません。通常、このパターンは少なくともgroup by部品を具体化するために使用できますが、ここでは MAX 集約によってそれが妨げられています。インデックス付きビューを維持し、削除または更新が存在する場合にある種の最大値を正確に維持するのは難しいため、これは理にかなっています (挿入は簡単です)。

オプション:

  1. ベース テーブルに適切にインデックスを付けます。
  2. データの非正規化バージョンを手動で維持します。
于 2015-10-24T10:44:10.147 に答える