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)。似乎我在这里不走运,因为索引视图不能包含派生表 OR TOP OR MAX OR 自联接。

关于如何创建索引视图的任何想法?

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

还有其他建议吗?

4

1 回答 1

1

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

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

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 回答