【问题标题】:How to design an efficient Like system?如何设计一个高效的Like系统?
【发布时间】:2016-10-11 13:40:18
【问题描述】:

我正在尝试为网站的现有 cmets 部分创建类似于 Facebook 的 Like/Unlike 系统,我在设计系统时需要帮助。

目前,网站上的每个产品都有一个 cmets 部分,会员可以发布和喜欢 cmets。我需要知道每个成员发布了多少个 cmets,他的每个 cmets 收到了多少个赞。当然,出于分析目的,我还需要知道谁也喜欢什么 cmets(部分原因是为了防止用户多次喜欢评论)。

对当前 cmets 模块实现 Like 系统的简单方法是在数据库中创建一个新表,该表具有 CommentID 和 UserID 的外键。然后,对于用户给评论的每一个“赞”,我都会在这个新表中插入一行,其中包含目标评论 ID 和用户 ID。

虽然这可能行得通,但大量的 cmets 和用户将导致此表快速增长,并且从这个巨大的表中检索记录和进行计数将变得缓慢且效率低下。我可以索引任一列,但我不知道它的效果如何。该网站拥有超过一百万个 cmets。

我正在使用 PHP 和 MySQL。对于这样一个拥有庞大数据库的系统,我应该如何设计一个 Like 系统,使其更加优化和稳定?

【问题讨论】:

  • 您可能希望将 LIKE 系统设计为非实时的。以“正确”的方式设计表格,但不要实时阅读它们以获得即时的 LIKE 计数。每隔几分钟、几小时等更新一次计数。
  • @AgRizzo “正确”的设计方式应该是什么样的?
  • 你的“天真”方式——即标准化。您需要知道哪个用户喜欢哪个评论,因此需要两列(至少):user_id 和 comment_id。
  • 我认为这太宽泛了,而且基于意见,不适合 SO - 这里发布的答案已经引起了更多的讨论,而不是单一的问答对。正如 OP 指出的那样,这可以通过多种方式完成,并且探索所有选项将很困难。
  • @HPierce 我不太明白你的反对意见。当然有多种方法可以做到这一点。大多数事情可以通过不同的方式来完成。但是您自己完成此任务的最佳方法可能是此问题的答案之一。以不同方式完成此任务的答案也可以为未来的读者提供很好的参考。

标签: php mysql optimization database-design system-design


【解决方案1】:

为了可扩展性,不要在同一个表中包含与其他内容相同的计数列。这是“垂直分区”有益的罕见情况。为什么? LIKEs/UNLIKEs 会来得又快又猛。如果执行递增/递减的代码碰到用于其他用途的表(例如评论的文本),则两者之间将出现不可接受的争用量。

此技巧是实现扩展到 Facebook 级别的众多步骤中的第一步。其他提示不是来自免费论坛,而是来自你必须聘请的聪明工程师团队才能达到那个水平。 (提示:分片、缓冲、显示估计等)

【讨论】:

    【解决方案2】:

    您主要关心的是大量计数,因此简单的做法是在您的 cmets 表中保留一个单独的计数。

    然后您可以创建一个TRIGGER,它根据喜欢/不喜欢增加/减少计数。

    这样你只使用大表来确定用户是否已经投票。

    【讨论】:

    • 所以我还要另外 2 个表,一个用于存储评论有多少喜欢,另一个用于存储用户发布了多少 cmets?我之前也想过这样的事情,但也在考虑,考虑到网站有超过一百万的cmets和几十万的用户,那么Likes表可能会增长到几千万行!所以每次当我需要知道谁喜欢评论的时候,我还需要遍历这个巨大的表格吗?
    • 另一件事是,假设我需要检查用户是否在投他喜欢之前已经喜欢了评论(以防止他多次喜欢评论),我仍然需要运行 throw那张大桌子,不是吗?
    • 不,您不需要新表,您可以将它们作为 cmets 表的一部分。并且为了防止用户评论/喜欢两次......您不需要“遍历”表格。假设您的意思是使用“贯穿”扫描整个表。有了一个好的索引,这应该很快。对于这样一个简单的数据集,几千万是微不足道的。
    猜你喜欢
    • 2022-08-04
    • 1970-01-01
    • 2012-03-04
    • 2020-11-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-08-29
    相关资源
    最近更新 更多