存储数据库记录的数量是多余的吗?

nfm*_*nfm 5 mysql database ruby-on-rails query-optimization denormalization

我正在使用Rails和MySQL,并且有一个基于行计数的效率问题.

我有一个Project模型has_many :donations.

我想计算一个项目的独特捐赠者数量.

projects表中有一个字段被调用num_donors,并在创建新的捐赠者时增加它是一个好主意吗?

或者@num_donors = Donor.count(:select => 'DISTINCT user_id')由于数据库优化,在效率方面类似或相似?这是否需要我为user_id我想要计算的任何其他字段创建索引?

总结捐赠总额的答案是否相同?

Joh*_*nFx 10

回答标题问题.是的,它是多余的,但你是否应该这样做取决于你的情况.

除非您知道性能问题,否则请在应用程序中动态计算计数和总计,不要存储它们.也就是说,除非您没有其他选择,否则不要存储计算值.

在大多数情况下,你不必诉诸于此而不应该这样做.

如果必须存储计算值,请执行以下操作:

  • 不要通过递增来保持最新状态.每次更新时重新计算所有数据的计数/总数.
  • 如果您没有大量更新,请将代码放在更新触发器中以使计数/总计保持最新.
  • 数据库冗余的问题在于,当数字不一致时,您不确定哪个是权威的.在文档中添加一条注释,如果源数据不同意并且可以覆盖,则源数据是权威来源.


Pet*_*ter 7

虽然它取决于数据库的大小,但这些是数据库专门研究的操作类型,因此它们应该很快.这可能是一个过早优化的情况 - 您应该首先不存储总数,从而使其更简单 - 并在必要时进行优化.


Lar*_*tig 6

请记住这句格言"有一只手表的男人总能知道时间.一个有两只手表的男人永远不会确定." 我只会存储派生的数字,如果:

性能问题阻止您在需要时获取派生数字(在这种情况下这不应该是一个问题,因为答案很可能从索引中获得)

要么

您有理由相信您通过程序员错误或故意或意外的用户操作丢失了主表中的记录.在这种情况下,您可以使用派生的数字来审核当前计算的数字.

  • 喜欢这句格言——以前没听说过。会牢记在心:) (2认同)

fra*_*ous 5

Peter 和 JohnFx 的答案是合理的,您建议的是数据库模式的非规范化,这可以提高读取性能,但会损害写入,同时另外将责任放在开发人员(或其他 DBMS 聪明人)身上,以防止您的数据库中出现不一致。数据集。

ActiveRecord 有一些内置功能可以自动管理has_many关系计数。查看计数器缓存上的 Railscast