在Microsoft SQL Server中存储昂贵的数据库计算

时间:2013-07-22 09:09:09

标签: sql sql-server database database-design

我正在使用Microsoft SQL Server。我想存储/缓存昂贵的计算,以便可以重复使用它们。在我的示例中,我有用户评分的项目,数据库模式如下所示:

User
 Id : int

Item
 Id : int

UserItemRating
 UserId (User)
 ItemId (Item)
 Rating : int

要获得评分最高的项目,我需要计算每个项目的平均评分(假设操作费用昂贵且UserItemRating经常更改/更新)。缓存此计算的好方法是什么?我应该向Item添加“AverageRating”列并创建一个更新它的触发器吗?创建一个视图?一个包含计算的临时表?

1 个答案:

答案 0 :(得分:3)

在SQL Server中,您将创建一个索引视图,如下所示:

create view dbo.ItemRatings
with schemabinding
as
    select
        ItemId,
        COUNT_BIG(*) as Cnt,
        SUM(Rating) as TotalRating
    from
        dbo.UserItemRating
    group by
        ItemId
go
create unique clustered index IX_ItemRatings on dbo.ItemRatings (ItemId)

关于索引视图的创建和使用有各种restrictions,但上述内容有效(假设UserItemRating模式中有dbo)。

注意事项:

  1. 必须是WITH SCHEMABINDING,这反过来意味着我们必须使用两部分名称来引用表格。
  2. 必须使用COUNT_BIG()才能使用GROUP BY子句
  3. 不直接包含平均值(实际上,索引视图中不允许AVG),但是,您可以通过将SUM()除以COUNT_BIG()来计算它。 / LI>
  4. 要在此视图上使用索引,您需要使用NOEXPAND提示进行查询,或者运行Enterprise Edition或更高版本。
  5. 为什么这比基于触发/表的解决方案更受欢迎?因为执行维护的代码内置于到SQL Server,并且其总体开销将低于任何其他解决方案。 (而且你不必花时间确保正确

    如果您使用的是Enterprise Edition,它甚至可以使用此索引视图,而不会直接引用它的查询 - 例如,如果要对要求COUNT的基表进行查询,{ {1}},甚至是SUM,它可能会使用此索引。