页面每次拉取用户没有读取过的文章,如何设计阅读状态数据库?

多用户多文章

页面每次从文章表拉取20条用户没有读取过的文章,

所以这个读取状态怎么存呢?

单独建立一个读取状态表,如何设计字段以及MYSQL如何查询更合适呢?

类似于抖音每次展示用户没有看过的视频,这个观看状态怎么设计储存呢?

阅读 2k
1 个回答

建立文章和观看用户的多对多关联表

补充:

来做个实验吧

users 用户表 50w,topics 文章表 500w 数据。

users_reads 阅读用户与文章关联表,模拟了 500w 数据,按日活用户 1w 来算,每日用户阅读10篇文章,两个月的时间差不多会产生500w。

表结构如下

// 表的结构 `users_reads`
CREATE TABLE `users_reads` (
  `id` bigint(20) UNSIGNED NOT NULL,
  `user_id` bigint(20) UNSIGNED NOT NULL COMMENT '用户 ID',
  `topic_id` bigint(20) UNSIGNED NOT NULL COMMENT '文章 ID',
  `created_at` timestamp NULL DEFAULT NULL,
  `updated_at` timestamp NULL DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;

ALTER TABLE `users_reads`
  ADD PRIMARY KEY (`id`),
  ADD KEY `users_reads_user_id_index` (`user_id`),
  ADD KEY `users_reads_topic_id_index` (`topic_id`);

ALTER TABLE `users_reads`
  MODIFY `id` bigint(20) UNSIGNED NOT NULL AUTO_INCREMENT;
COMMIT;

准备拿用户 365908 来做实验,让 365908 用户的已读文章不至于太少,目前已读文章大约是 1w。

SELECT ur.user_id, COUNT(*) as count
FROM `users_reads` as ur
GROUP BY user_id
ORDER BY count DESC
LIMIT 0, 10
user_id    count       
365908    10011    
472884    27    
9539    27    
95695    26    
224228    26    
118741    26    
359702    26    
185407    26    
18894    25    
44422    25    

开始实验,查出用户30条未读文章,实验结果如下

SELECT ur.topic_id, ur.user_id, t.*
FROM (
    SELECT * 
    FROM `users_reads` 
    WHERE user_id = 365908
) as ur
RIGHT JOIN topics as t
ON ur.topic_id = t.id
WHERE ur.topic_id is null
ORDER BY id DESC
LIMIT 0, 30

// 正在显示第 0 - 29 行 (共 30 行, 查询花费 0.0009 秒。)

个人感觉,如果利用好索引的话,Mysql 不至于那么不经打。

实验可能存在纰漏,欢迎指正。

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题