SQL 服务器中使用索引视图的基本事件源

Basic Event Sourcing in SQL Server using Indexed Views

我正在尝试使用 SQL 服务器实现非常基本的事件溯源。没有图书馆,没有其他服务器,没有什么特别的,只是使用 SQL 服务器的基础知识。

假设我有这个 table:

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;

现在我将在 table 中拥有数百万行,并在视图上进行许多并发读取。所以我想为它编制索引(SQL 服务器索引视图)。看来我在这里运气不好,因为索引视图不能包含派生的 tables OR TOP OR MAX OR self-joins.

关于如何创建索引视图有什么想法吗?

如果那不可能,我可以使用 INSTEAD OF 触发器,它更新 table 中的 IsLatest BIT 列,并基于此过滤器创建索引视图。

还有其他建议吗?

您现有的视图定义不会起作用,因为 SELECT TOP 1 Id FROM table ORDER BY CreatedOn DESC, Id DESC returns 只有一行,但您需要一个 每外行 .

无法使用索引视图具体化此查询。即使您像这样重新制定查询:

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. 正确索引基数 table。
  2. 手动维护数据的非规范化版本。