评论系统表结构设计--简单模型
一、采用id,parent_id(父节点id)来存储
1、表结构如下:
2、假设表中数据为:
3、想实现的效果如下,打开评论显示第一张页面,即查询所有一级评论,点击“展开1440条回复”查询对应一级评论前三条评论,
4、当查询对应一级评论前三条评论时,就需要进行递归查询。
-- 分页查询一级评论,查询前20条
-- SELECT * FROM tb_comments WHERE parent_id = 0 LIMIT 0,20;
-- 当点击“展开1440条回复”时,比如我想查询前3条,就需要进行递归查询,不管是在java代码里递归还是在数据库递归
WITH RECURSIVE comment_tree AS (-- 锚点:获取目标评论SELECT *,0 as replied_user_id, 1 AS depth FROM tb_comments WHERE parent_id = 1UNION ALL-- 递归获取所有后代评论SELECT c.*, ct.user_id AS replied_user_id, ct.depth + 1 FROM tb_comments cINNER JOIN comment_tree ct ON c.parent_id = ct.id
)SELECT * FROM comment_tree
ORDER BY create_time ASC
LIMIT 3;
递归查询结果如下:
缺点:如果用户互相回复层级过多,那么递归查询效率过低,因此重新设计表结构。
二、采用id,parent_id(顶级评论id),reply_id(回复评论id)存储
1、表结构:
2、数据
3、如果想实现如下效果,那么查询过程为:
-- 分页查询一级评论,查询前20条
-- SELECT * FROM tb_comments WHERE parent_id = 0 LIMIT 0,20;
-- 当点击“展开1440条回复”时,比如我想查询前3条,直接查询一层评论的所有子节点即可
SELECT t1.*,CASE WHEN t2.parent_id = 0 THEN0 ELSE t2.user_id END AS replied_user_id
FROMtb_comments t1LEFT JOIN tb_comments t2 ON t1.reply_id = t2.id
WHEREt1.parent_id = 1
ORDER BYcreate_time
LIMIT 0,3
查询结果:
由此可看,不采用递归也能实现上述效果,而且效率高一些。
【注】方案二还适用于引用评论进行回复。
参考:1、系统设计-评论系统关键设计思路与入门_哔哩哔哩_bilibili
2、竟然还要考虑这些字段?我是如何做评论表结构设计的。_哔哩哔哩_bilibili