首页 > 解决方案 > 保存用户交互并呈现它们

问题描述

我有一个用户投票投票的网站。他们也可以喜欢这些民意调查。当他们滚动浏览他们的提要时,他们喜欢的问题将由一个被填充的类似图标表示(有点像 Facebook 或 Instagram)。如果他们已经在生成的提要上投票支持投票,他们的投票也将显示。

随着网站规模的扩大,因为现在有数百万张选票,所以要为每个问题查询他们的喜欢和选票需要很长时间。我的问题是如何使这个过程更快?目前,我使用 MySQL 来存储数据。

我的想法是使用像 Redis 这样的缓存存储,并以这种类型的结构存储他们对每个问题的所有喜欢和投票:

User_id:
  likes: [question_ids]
  votes: [question_ids]

其中 user_id 是包含数组类型值的字典键。提要从缓存中加载,对于每个问题,我们检查该问题是否被用户喜欢或投票。我不确定这种方法是否是“最好的”,或者是否有另一种做事方式。我想知道 Facebook、Instagram、Twitter 等如何保存用户交互以及他们如何查询它们。

表:

Question Table (simplified)
id   question   total_votes  total_likes

Choice Table  (One question has two choices)
id  question_id choice votes

Voting table
id  user_id  choice_id

Like Table
id  user_id  question_id

查询以获取最新问题:

SELECT  `core_question`.`id`, `core_question`.`user_id`,
        `core_question`.`status`,
        `core_question`.`total_votes`, `core_question`.`like_count`,
        `core_question`.`comment_count`, `core_question`.`created_at`,
        `core_question`.`slug`, `core_question`.`flag`,
        `core_question`.`spam_flag`,
        ( SELECT  U0.`is_liked`
            FROM  `core_like` U0
            WHERE (U0.`question_id` = `core_question`.`id`
              AND  U0.`user_id` = 1)
            LIMIT  1
        ) AS `like_selected`, 
        ( SELECT  U0.`choice_id`
            FROM  `core_voting` U0
            INNER JOIN  `core_choice` U1  ON (U0.`choice_id` = U1.`id`)
            WHERE (U1.`question_id` = `core_question`.`id`
              AND  U0.`user_id` = 1)
            LIMIT  1) AS `choice_selected`,
        COUNT(CASE WHEN `oauth_following`.`follower_id` = 1
                   THEN `oauth_following`.`id`
                   ELSE NULL END ) AS `is_following`
    FROM  `core_question`
    INNER JOIN  `oauth_user`  ON (`core_question`.`user_id` = `oauth_user`.`id`)
    LEFT OUTER JOIN  `oauth_following`  ON (`oauth_user`.`id` =
                               `oauth_following`.`target_id`)
    WHERE  NOT (`core_question`.`user_id` IN (4, 5, 6, 7))
    GROUP BY  `core_question`.`id`
    ORDER BY  `core_question`.`id` DESC

标签: mysqldatabasecachingnosql

解决方案


我建议这些索引:

core_question:    INDEX(user_id)
oauth_following:  INDEX(target_id,  follower_id)
core_like:        INDEX(question_id, user_id,  is_liked)
core_choice:      INDEX(question_id)
core_voting:      INDEX(user_id, choice_id)

推荐阅读