【问题标题】:Should a column of user votes be updated in real-time or once-a-day, and how?用户投票栏应该实时更新还是每天更新一次,如何更新?
【发布时间】:2018-06-17 03:48:01
【问题描述】:

在我的一个网站上,用户可以互相投票。我有一个Votes 表,其中每一行对应一个投票。

我想开始向用户显示他们的总票数,这只是他们在Votes 表中获得的票数的总和。我应该实时计算,还是应该每天计算一次。这种情况的“最佳实践”是什么(假设有数十万票并且还在增长)?

实时很容易,但一天一次就没有那么简单了。我假设我需要做一个 Cron 工作,但我到底该怎么做呢?我知道我需要遍历每个用户并计算他们在Votes 表中收到的投票的总和,但是我是否需要从第一次投票开始每天做一个完整的总和并保存,还是我应该只将 new 投票(自上次更新以来)添加到现有总和并保存?

如果是后者,那么我将如何做到这一点并跟踪所有内容,以免错过任何选票或添加两次?

【问题讨论】:

    标签: mysql database-design


    【解决方案1】:

    处理这个问题的标准方法是denormalization,这基本上意味着存储可以通过查询确定的数据。它不仅是唯一真正的scalable 解决方案,而且相当简单并且性能卓越。以下是你如何实现它:

    total_votes 列添加到users 表中,并通过在投票数据更改时触发的触发器保持正确。

    类似这样的:

    delimiter //
    
    create trigger vote_trigger
    after insert on votes
    for each row
    begin
        update users set
        total_votes = total_votes + 1
        where users.user_id = new.user_id;
    end; //
    
    delimiter ;
    

    为行删除和行更新创建其他类似的触发器。


    最初,运行一个查询来填充所有值,像这样只运行一次,而您的系统处于离线或只读模式:

    update users set
    total_votes = (select count(*) from votes where user_id = users.user_id);
    

    但执行此查询时,触发器将保持total_votes 的值正确(即与votes 表同步)。

    【讨论】:

    • 有趣。但是,如果我正确理解触发器,是否每次进行新的投票时都会重新计算每个人的总票数?如果是这样,那是不是效率很低,还是我理解不正确(例如,我不确定 new.user_id 是什么)?
    • 每当您进行非规范化(这是一种合法的性能优化)时,请务必编写工具以确保您的重复值保持同步。如果不这样做,有时会在缓存值和实际值之间产生偏差。
    • @tadman:我不确定我理解你的意思,你能举个例子吗?谢谢。波西米亚人:你收到我上面的问题了吗?谢谢。
    • 在这种特殊情况下,我的意思是您需要创建一种方法来使用正确的计数填充total_votes。有时,您可能会在该列中有不正确的值。示例初始查询是如何执行此操作的一个示例,但可能还有其他更有效的方法。
    • @Programmer 否 - 触发器正在增加刚刚为他/她插入投票的用户的 total_votes
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-03-25
    • 1970-01-01
    • 1970-01-01
    • 2015-08-31
    • 2021-07-04
    • 1970-01-01
    相关资源
    最近更新 更多