我的数据库中有很多表格,用于保存用户可以喜欢,不喜欢,共享,喜欢等项目的信息(照片,文章,视频)。
每次用户对某个项目执行操作时,都会将其记录在如下的简单表格中:
ItemID | UserID | Liked | Shared | Favourited
1 1 NULL 1 NULL
2 25 1 1 1
3 18 0 NULL NULL
当我编写查询以从表格中返回项目列表(例如照片)时,我还想返回每个项目所拥有的喜欢,股票等的总数。目前我正在使用嵌套的SELECT语句动态计算它。如果我的项目表的大小增加了数十万,并且我经常需要关于喜欢,股票等的统计数据,那么继续计算动态数据是否安全,或者它们是否应该存储在数据库中的某个位置?
答案 0 :(得分:4)
我建议不要存储总计,因为这似乎是一个事务性数据库,并且您将频繁插入行,因此如果您存储总计,则每次插入行时,都需要更新总计。
因此实际上,表中的每个插入后面都会跟一个更新语句,以便更新总数。对于事务数据库来说,这听起来很糟糕。
对于数据仓库来说,存储总计是一个很好的选择,数据几乎不会发生变化。
我的建议是创建视图,它会动态计算总数。添加适当的索引以使这些查询有效。当您的数据变得太大以至于表上的索引都做得不够时,请考虑索引视图。
答案 1 :(得分:2)
存储总数是邪恶的,因为:
答案 2 :(得分:1)
如果是我,我会偶尔计算一次并将结果存储在另一张表中。如果计数对于像“有多少人喜欢小猫”这样的东西而言不是那么准确,那么这并不是什么大问题。
答案 3 :(得分:1)
另一方面,如果您希望获得一百万个“观看次数”,并且必须COUNT(*)
来检索该计数,那么Performance可能会否决“邪恶”。
对于大容量情况,我建议以下之一:
计划A:即时进行计数。 UPDATE ViewCounts SET ct = ct + 1 WHERE page_id = ?
请注意,这是故意与“页面”的其余元信息放在单独的表中。这是为了减少两者之间的干扰。 (或者,您也可以将每个“视图”的详细信息保留在另一个表中。)
计划B:有一张表格,其中包含有关每个“视图”的信息,但是每小时(每天)每小时(一天)执行COUNT(*)
,并将结果放入“摘要表”中。然后从该表中SUM(subtotal)
获得总体视图。这样的表格还可以为视图中的“趋势”提供图表信息。
注意:这两个计划都假定事实之后数据不会更改。处理原始“视图”表中的删除内容变得很复杂。