【问题标题】:Storing a bunch of foreign keys efficiently (Serialize vs New Table)有效地存储一堆外键(序列化与新表)
【发布时间】:2012-01-17 20:38:16
【问题描述】:

我需要保留查看过某条内容的user_ids 的列表,以计算唯一用户查看次数。 user_id 是一个 INT(10) 字段。

我可以使用user_idcontent_idviewed 创建一个表,并在每次用户查看内容时添加一行,但这似乎很慢。对于用户查看的每条内容,我都必须查询类似

SELECT COUNT(*) FROM viewed_table WHERE content_id = $content_id;

获取浏览量,然后

SELECT COUNT(*) FROM viewed_table WHERE user_id = $user_id AND content_id = $content_id;

查看用户是否查看过该内容,如果没有则插入一行。 (每次用户查看某物时,都会有 2 或 3 个额外的查询)。

或者...

每次我添加user_id 时,我是否应该将viewed 字段添加到我的内容表和unserialize() / serialize() 数组? json_encode() 是另一个类似的选项,它在大型数据集上似乎更快。

对于成长中的网站来说,哪个选项最快/最具可扩展性?感谢您的帮助!

【问题讨论】:

    标签: mysql sql


    【解决方案1】:

    经验法则:序列化一般的关系数据,特别是外键 == 通往地狱的高速公路。

    有一个表格,您可以在其中存储所有视图的总和,并且您只能增加/减少它。那应该比SELECT COUNT(*) FROM viewed_table WHERE content_id = $content_id;

    查看给定用户是否已查看给定页面SELECT 1 FROM viewed_table WHERE user_id = $user_id AND content_id = $content_id LIMIT 1;。这将返回 0 或 1 行,因此您只需要检查即可。

    【讨论】:

      【解决方案2】:

      你可以这样做:

      viewed_table
      ----------------------------
      user_id int(10)
      content_id int(10)
      primary key (user_id, content_id)
      

      插入记录:

      INSERT IGNORE INTO viewed_table (user_id, content_id) VALUES ($user_id, $content_id)
      

      您的受影响行数将显示这是否是新行(用户尚未查看内容)。该选项不需要选择。

      如果您希望实现总计表,这也是您将所选 content_id 的总计加一的点。

      viewed_table_totals
      ----------------------------
      content_id int(10)
      view_count int(10)
      primary key (content_id)
      

      更新行:

      INSERT INTO viewed_table_totals (content_id, view_count) VALUES($content_id, 1)
        ON DUPLICATE KEY UPDATE view_count = view_count + 1
      

      由于您想要唯一的访问,因此您无法避免存储每个用户访问。

      【讨论】:

        【解决方案3】:

        毫无疑问是第一个选项。

        每次您想要计算查看次数或每当有人阅读一篇文章时序列化/反序列化 id 列表的成本将比在索引良好的第二张表上进行 COUNT 慢几个数量级。

        您可以通过将计数存储在内存中(使用 Memcached 或 Redis 之类的东西)或通过向内容表添加 view_count 列并在添加到 view_table 时增加该数字来进一步改进这一点。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2011-02-06
          • 1970-01-01
          • 1970-01-01
          • 2021-08-26
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2015-11-09
          相关资源
          最近更新 更多