Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/sql-server/23.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
Sql server 存储总计还是动态计算?_Sql Server_Database Design_Sql Server 2012 - Fatal编程技术网

Sql server 存储总计还是动态计算?

Sql server 存储总计还是动态计算?,sql-server,database-design,sql-server-2012,Sql Server,Database Design,Sql Server 2012,我的数据库中有许多表,其中包含用户喜欢、不喜欢、共享、喜爱等项目(照片、文章、视频)的信息 每次用户对某个项目执行操作时,都会将其记录在一个简单的表格中,如下所示: ItemID | UserID | Liked | Shared | Favourited 1 1 NULL 1 NULL 2 25 1 1 1 3 18 0 NULL NULL

我的数据库中有许多表,其中包含用户喜欢、不喜欢、共享、喜爱等项目(照片、文章、视频)的信息

每次用户对某个项目执行操作时,都会将其记录在一个简单的表格中,如下所示:

ItemID | UserID  | Liked | Shared | Favourited
1        1         NULL    1        NULL
2        25        1       1        1
3        18        0       NULL     NULL

当我编写一个查询以返回表中的项目列表(例如照片)时,我还希望返回每个项目拥有的喜欢、共享等的总数。目前,我正在使用嵌套的SELECT语句动态地计算它。如果我的物品表的大小增加了数十万,并且我经常需要喜欢、共享等方面的统计数据,那么继续动态计算统计数据是安全的,还是应该将它们作为总计存储在数据库中的某个位置?

我建议不要存储总计,由于这似乎是一个事务性数据库,您将非常频繁地插入行,因此,如果您存储总计,则每次插入行时,都需要更新总计

因此,实际上,表中的每个insert后面都会有一个update语句,以保持总数的更新。对于事务数据库来说,这听起来是一个非常糟糕的设计

对于数据几乎不发生变化(如果有的话)的数据仓库来说,存储总计是一个很好的选择


我的建议是创建视图,以便在运行中为您计算总数。添加适当的索引以提高这些查询的效率。当您的数据增长过大以至于表上的索引甚至不够做时,请考虑索引视图。 如果是我,我会每隔一段时间计算一次,然后将结果存储到另一个表中。如果“有多少人喜欢小猫”这样的数字不能精确到第二位,那也没什么大不了的。

存储总数是件坏事,因为:

  • 它是一种缓存形式,其本身是邪恶的(可能不一致,或者最好是不平凡的)。有关更多信息,请参阅
  • 这可能是错误的!除非涵盖所有数据修改的可能性(比如触发器),否则可能会有错误-即存储的总数可能不正确。错误数据比慢速数据糟糕1000倍
  • 更复杂:您已经向系统添加了另一个方面。要避免复杂性
  • 不必要或无效-除非您有文档证明通过查询执行此操作是不可行的,并且您一直困扰着所有查询优化,否则您不需要执行此操作。即使你认为你确实需要它,你也可能不需要。例如,您可以将您的操作分为使用dara仓库存储稳定数据(例如,超过1周的数据)和使用实时系统存储最近的所有数据,这将限制查询管仅扫描最近一周的数据(执行正常)。如果性能仍然存在问题,则将“实时”窗口缩小到一天。我就是这么做的,效果很好

另一方面,如果您希望获得一百万个“视图”,并且您必须
COUNT(*)
来检索该计数,那么性能可能会推翻“邪恶”

对于高容量情况,我建议采用以下方法之一:

计划A:快速计数
updateviewcounts SET ct=ct+1,其中page_id=?
请注意,这与“页面”的其余元信息故意放在一个单独的表中。这是为了减少两者之间的干扰。(也可以选择在另一个表中保留每个“视图”的详细信息。)

计划B:有一个包含每个“视图”信息的表格,但每小时(或每天?)对小时/天执行
COUNT(*)
,并将结果放入“汇总表”。然后从该表中
SUM(subtotal)
获得总体视图。这样的表格还可以为视图中的“趋势”提供图表信息

注意:这两个计划都假设数据在事实发生后不会改变。处理原始“视图”表中的删除变得复杂