MySQL-计算行数与设置计数器

MySQL-计算行数与设置计数器,mysql,sql,Mysql,Sql,我有两张表帖子和投票。在这里,表格投票可以是1(向上投票)或-1(向下投票)。现在,如果我需要在一篇文章上获得总票数(上升票-下降票),我可以用两种方法 使用count(*)从投票数表中计算该帖子的得票数,然后进行计算 设置计数器列投票\u counter并在用户每次向上投票或向下投票时递增或递减。然后只需提取投票\u计数器 我的问题是哪一个更好,在什么条件下。说到条件,我指的是可伸缩性、峰值时间等因素 据我所知,如果我使用方法1,对于一个有数百万行的表,count(*)可能是一个繁重的操作。为

我有两张表
帖子
投票
。在这里,表格投票可以是1(向上投票)或-1(向下投票)。现在,如果我需要在一篇文章上获得总票数(上升票-下降票),我可以用两种方法

  • 使用
    count(*)
    投票数表中计算该帖子的得票数,然后进行计算
  • 设置计数器列
    投票\u counter
    并在用户每次向上投票或向下投票时递增或递减。然后只需提取
    投票\u计数器
  • 我的问题是哪一个更好,在什么条件下。说到条件,我指的是可伸缩性、峰值时间等因素


    据我所知,如果我使用方法1,对于一个有数百万行的表,
    count(*)
    可能是一个繁重的操作。为了避免这种情况,如果我在高峰时间使用计数器,那么投票计数列可能会死锁,太多用户试图更新计数器


    还有第三种方法比这两种方法都好,而且实现起来也很简单吗?

    由于这听起来很像StackExchange,我将在meta上向您介绍站点上使用的数据库模式。投票表如下所示:

    投票表:

    • Id
    • posted
    • VoteTypeId
      ,以下值之一:

      1 - AcceptedByOriginator
      2 - UpMod
      3 - DownMod
      4 - Offensive
      5 - Favorite (if VoteTypeId = 5, UserId will be populated)
      6 - Close
      7 - Reopen
      8 - BountyStart (if VoteTypeId = 8, UserId will be populated)
      9 - BountyClose
      10 - Deletion
      11 - Undeletion
      12 - Spam
      15 - ModeratorReview  
      16 - ApproveEditSuggestion
      
    • UserId
      (仅当VoteTypeId为5或8时出现)

    • CreationDate
    • 赏金金额
      (仅当VoteTypeId为8或9时出现)
    基于此,它的运行方式似乎是:

    SELECT VoteTypeId FROM Votes WHERE VoteTypeId = 2 OR VoteTypeId = 3
    
    然后根据该值进行数学计算:

    int score = 0;
    for each vote in voteQueryResults
        if(vote == 2) score++;
        if(vote == 3) score--;
    

    即使有数以百万计的结果,这也可能是一个非常快速的操作,因为它非常简单。

    这两种方法代表了实现复杂性和速度之间的共同折衷

    • 第一种方法实现起来非常简单,因为它不需要您进行任何额外的编码
    • 第二种方法可能要快得多,特别是当您需要在一个大表中计算一小部分项时
    • 第一种方法可以通过精心设计的索引来加速。RDBMS可以从索引中检索一些记录,并使用它们进行计数,而不是搜索整个表
    第二种方法可能很快变得非常复杂:

      <> LI>当用户被删除时,您需要考虑计数发生的情况。 你应该考虑当投票表被程序外的工具操纵时会发生什么。例如,当当前计数与单个计数一起存储时,合并两个数据库中的记录可能要复杂得多

    我将从第一种方法开始,看看它的性能如何。然后我会尝试用索引优化它。最后,我会考虑使用第二种方法,可能会编写触发器来自动更新计数。

    “VoTeSuff计数器列可能会死锁,太多用户试图更新计数器”——为什么这里应该是死锁?比如说,1000名用户试图每秒钟对一篇文章进行投票。但是数据库服务器不能在一秒钟内处理1000个操作。这就是我所说的那种情况。当你有1000个用户同时在你的网站上做一些事情时,你不必担心增加一个计数器。@zerkms好吧,这是我的大学模拟项目。1K用户一秒钟的真实时间是一件大事!这在堆栈溢出时不是很快,因为它们也缓存分数。如果扩展分数,则该操作需要一段时间,因此该操作仅对2k+用户可用