Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/68.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在Microsoft SQL server中存储昂贵的数据库计算_Sql_Sql Server_Database_Database Design - Fatal编程技术网

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

在Microsoft SQL server中存储昂贵的数据库计算,sql,sql-server,database,database-design,Sql,Sql Server,Database,Database Design,我正在使用Microsoft SQL Server。我想存储/缓存昂贵的计算,以便可以重用它们。在我的示例中,我有按用户分级的项目,数据库模式如下所示: User Id : int Item Id : int UserItemRating UserId (User) ItemId (Item) Rating : int create view dbo.ItemRatings with schemabinding as select ItemId,

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

User
 Id : int

Item
 Id : int

UserItemRating
 UserId (User)
 ItemId (Item)
 Rating : int
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)

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

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

User
 Id : int

Item
 Id : int

UserItemRating
 UserId (User)
 ItemId (Item)
 Rating : int
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)
关于索引视图的创建和使用有多种不同的方法,但上述方法是有效的(假设
UserItemRating
位于
dbo
模式中)

注意事项:

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


    如果您使用的是Enterprise Edition,它甚至可以使用此索引视图,而无需您的查询直接引用它-例如,如果您要对要求计数
    总和
    、甚至是平均值)的基表进行查询,它可能会使用此索引。

    则“转到”解决方案是“不要存储您可以轻松计算的数据”,并添加了“除非重新计算数据的性能受到禁止”的但书。如果您决定存储计算的答案,最好的解决方案是(如果可能的话)使用您的数据库系统本机支持的存储计算数据的解决方案(例如索引视图或物化视图)-但要了解更多信息,我们需要知道您使用的是什么RDBMS。谢谢。更改了问题的措辞。