构建类Facebook链接信息流:多数据表内容展示需求问询
嘿,我来帮你搞定这个类似Facebook信息流的查询需求!结合你给出的三张表结构,我整理了一套可行的SQL方案,还会拆解每个部分帮你理解~
解决方案
核心思路是先获取用户关注的所有对象(用户、页面、群组),再分别拉取这三类对象产生的符合时间要求的内容,最后聚合排序展示。
完整SQL查询
假设你的表结构包含必要的关联字段(比如followers表有follower_id表示关注人ID,shares表有group_id标记分享到的群组),查询代码如下:
WITH user_follows AS ( -- 先获取当前用户关注的所有对象(用户、页面、群组) SELECT user_id, type FROM followers WHERE follower_id = @current_user_id -- 替换成当前登录用户的ID ) -- 1. 页面发布的链接 SELECT 'page_post' AS content_type, -- 标记内容类型,方便前端区分展示 l.link_id AS content_id, l.url, l.content, l.date, l.page_id AS source_id -- 可选:页面ID,用于关联页面信息 FROM links l JOIN user_follows uf ON l.page_id = uf.user_id AND uf.type = 1 -- 关联用户关注的页面 WHERE l.date BETWEEN DATE_SUB(CURDATE(), INTERVAL 1 DAY) AND CURDATE() -- 筛选昨日到今日的内容 UNION ALL -- 用UNION ALL避免去重,保留所有符合条件的内容 -- 2. 用户分享的链接(关注的用户分享的内容) SELECT 'user_share' AS content_type, s.share_id AS content_id, l.url, CONCAT('分享自用户 ', s.user_id, ': ', l.content) AS content, -- 拼接展示文本 s.date, s.user_id AS source_id -- 可选:分享者用户ID FROM shares s JOIN links l ON s.link_id = l.link_id -- 关联原链接内容 JOIN user_follows uf ON s.user_id = uf.user_id AND uf.type = 0 -- 关联用户关注的用户 WHERE s.date BETWEEN DATE_SUB(CURDATE(), INTERVAL 1 DAY) AND CURDATE() UNION ALL -- 3. 群组内用户分享的链接(关注的群组内的内容) SELECT 'group_share' AS content_type, s.share_id AS content_id, l.url, CONCAT('群组 ', s.group_id, '内分享: ', l.content) AS content, -- 拼接展示文本 s.date, s.group_id AS source_id -- 可选:群组ID FROM shares s JOIN links l ON s.link_id = l.link_id -- 关联原链接内容 JOIN user_follows uf ON s.group_id = uf.user_id AND uf.type = 2 -- 关联用户关注的群组 WHERE s.date BETWEEN DATE_SUB(CURDATE(), INTERVAL 1 DAY) AND CURDATE() -- 排序:先按日期倒序(最新内容在前),同日期内随机打乱 ORDER BY date DESC, RAND();
代码拆解
- CTE
user_follows:提前筛选出当前用户关注的所有对象,避免后续重复写followers表的查询条件,让代码更简洁。 - 三类内容聚合:
- 页面发布内容:直接关联
links和user_follows的页面类型(type=1); - 用户分享内容:关联
shares、原链接links和用户关注的用户(type=0); - 群组分享内容:关联
shares、原链接links和用户关注的群组(type=2);
- 页面发布内容:直接关联
- 时间筛选:用
DATE_SUB(CURDATE(), INTERVAL 1 DAY)获取昨日零点,CURDATE()获取今日零点,确保只拉取昨日到今日的内容。 - 排序逻辑:先按日期倒序保证最新内容优先,再用
RAND()让同一天的内容随机展示,符合信息流的自然感。
注意事项
- 如果你的表结构没有
group_id,可以根据实际存储群组分享的字段调整关联条件; - 要是不需要区分内容类型,直接去掉
content_type字段即可; - 如果要包含今日实时的内容(不是到零点),把日期筛选条件改成
l.date >= NOW() - INTERVAL 1 DAY; - 若想完全随机展示(不按日期排序),把
ORDER BY改成ORDER BY RAND(),但通常信息流还是优先展示最新内容体验更好。
内容的提问来源于stack exchange,提问作者Valter Sousa Cardoso
相关产品推荐
相关产品推荐

