【问题标题】:Basic Event Sourcing in SQL Server using Indexed ViewsSQL Server 中使用索引视图的基本事件溯源
【发布时间】:2015-10-24 18:44:10
【问题描述】:

我正在尝试使用 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 列,并基于此过滤器创建索引视图。

还有其他建议吗?

【问题讨论】:

    标签: sql-server materialized-views event-sourcing indexed-views


    【解决方案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. 手动维护数据的非规范化版本。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2012-09-03
      • 2012-03-01
      • 2011-02-16
      • 1970-01-01
      • 2012-02-18
      • 2011-07-16
      • 2018-02-19
      相关资源
      最近更新 更多