设计数据库中的“总计”字段

时间:2012-02-21 04:29:27

标签: mysql sql database database-design

我正在尝试为我的数据库(MySQL)找到最佳解决方案,但我仍然坚持决定是否存储Total列。

这是我的数据库的简化版本:

我有一个Team表,一个Game表和一个'Score'表。 Game{teamId, scoreId,...},而Score表格将{scoreId, Score,...}(此处......表示表格中的其他列)。

在主页上,我需要显示团队列表及其分数。随着时间的推移,团队的数量将增加到100s,而得分列表将增长到100000s。这是首选方式:

  • 每次请求页面时,我应该总结得分并与团队一起展示。 (我不想缓存因为分数会不断变化) OR
  • 我应该在total_score表格中有一个Team字段,每次将新分数添加到该分组的分数表中时,我会更新团队的total_score吗?

两者中哪一个是更好的选择还是还有其他更好的方法?

4 个答案:

答案 0 :(得分:2)

在决定存储计算值时,我使用了两条准则。在最好的世界中,这两种说法都是正确的。

1)该值必须是计算上昂贵的 2)该值必须具有较低的变化概率。

如果计算价值的成本非常高,但每天都在变化,我可能会考虑做一个更新价值的夜间工作。

从没有总列开始,只有在遇到性能问题时才添加它。

答案 1 :(得分:1)

在请求时计算总和对于准确性更好,但效率更差。

字段中的缓存总数(显着)会提高某些查询的性能,但会增加代码复杂性或显示陈旧数据(如果您不是同时更新缓存值,而是通过cron作业更新)。

取决于你! :)

答案 2 :(得分:1)

我同意不应使用计算值,除非是特殊情况,例如数据库的月末快照。

我只需创建一个视图,视图中的一列等于您计算的总列数。然后,您可以查询视图而不是基表。

答案 3 :(得分:0)

取决于您的分数更新的频率以及“分数”的含义

案例1:分数是LIVE分数

如果“得分”是“蟋蟀或棒球比赛中得分”或“摔​​跤比赛或桌上比赛得分”的实时比分,那么我真的不明白是否需要显示“跑步”得分的“总和”。然而,在某些情况下,这可能也是一个要求,比如显示一支球队迄今为止得分的总得分+目前在比赛中进行的比赛得分。

在这种情况下,我建议您使用另一个选项,即第一个和第二个选项的组合

团队表中的Total_score会很好,您的数据模型会略有变化。

在得分表中添加一个名为LIVE的新列,对于实时匹配的完成匹配1将为0(并且可选-1表示匹配即将开始,但得分不会更新)

现在将两个表联合起来就像

select team_id,sum(total_sore) from (
select team_id,total_score from team
union
select team_id,sum(score) total_score from scores where live = 1 group by team_id)subquery
group by team_id

案例2:分数只是一个结果

只需直接查询数据库(您的第一个选项),因为结果只会在游戏结束后更新,而更新实际上它将是得分表中的新条目。

如果我的假设是正确的,那么只有在比赛结束后才能更新分数。此外,当考虑团队所玩的游戏时,更新的频率会更低。