让我们假设一个用户正在关注成千上万的其他人,
这些人定期发送新闻,在他/她的页面中,我们的用户只想看到这些人的最新新闻(分页(。
最有效的方法是什么?
这就是我目前正在做的:
- 在数据库中创建一个名为
following
的表,每个后面都添加了id
、user_id
、following_user_id
- 获取用户的following_user_ids列表
- 获取
user_id
(新闻发布者id(为IN(...following_user_ids...)
的所有新闻
例如,如果我们的用户id是1:
SELECT `following_user_id` FROM `following` WHERE `user_id` = 1; /* This is used in the IN() below */
SELECT * FROM `news` WHERE `user_id` IN (4,11,7,...following_user_ids....) ORDER BY `id` DESC limit 50 offset 0
/* Of course the `user_id` is indexed in the `news` table */
但是,如果用户关注成千上万的人,并且news
表很大,我想IN (... thousands of IDs ...)
会很慢吗?
那么,有没有更有效的方法来做到这一点呢?
编辑:
如果任何人也有这个问题,只要坚持使用In方法,它比我的JOIN快得多。
select
news.*
from
news
join following on news.user_id=following.following_user_id
where
following.user_id=1
分页
OFFSET
有问题。当他向前/向后翻页,而其他人正在插入新行时,他会错过故事或在连续的页面上看到同一个故事两次。
解决方案是";记住你在哪里停下来";。更多信息:http://mysql.rjweb.org/doc.php/pagination
加入
JOIN
方法更干净,但不一定更快。无论哪种情况,最终的结果都是一大堆故事,他只对其中一页的价值感兴趣。把其余的东西推来推去代价高昂。
解决方法是只查找故事的ID,同时查找页面的价值然后查找(通过另一个JOIN
(每个故事的其余数据。
预构建列表
尽管如此,如果有成千上万的追随者(或者在特朗普的情况下有数百万的追随者(,成本会相当高。有一种以CCD_ 13需要四处运行和存储信息为代价使CCD_ 12更快的技术。
有一个新的3列表:(1(follower_id,(2(timestamp,(3(story_id。每当发布故事时,每个关注者都会向该表中添加一行。当一个追随者想要最新的故事时,他就坐在这张桌子上(或者至少id是(。
更多信息:http://mysql.rjweb.org/doc.php/lists
您可以使用"limit"功能来限制搜索,每次用户想要更多信息时都需要更新该功能:
LIMIT [offset,] row_count;
把它放在你的例子中是这样的,把这个选择保存在一个临时表变量中:
SELECT * FROM `following_user_ids` ORDER BY `id` DESC limit rowcount offset offset_variable;
如果你想以社交媒体为例,你可以在每次用户要求更多帖子时更新限制,这样用户就可以看到他关注的几个帖子。