数据库表设计(邻接表、路径枚举、嵌套集、闭包表)

 1.邻接表

 用邻接表记录这个评论的数据(comments 表):

comment_id parent_id author comment
1 0 小明 我不大认同这个观点
2 1 小张 我也不认同
3 2 小红 我同意楼上
4 1 小全 你为什么不认同呢
5 4 小明 我以前遇到过这情况
6 5 小张 那也不代表你所说是对的
7 5 小新 这个视情况而定吧

  

 这种表设计,查询所有子节点和所有父节点非常痛苦

2.路径枚举

comment_id path author comment
1 1 小明 我不大认同这个观点
2 1/2 小张 我也不认同
3 1/2/3 小红 我同意楼上
4 1/4 小全 你为什么不认同呢
5 1/4/5 小明 我以前遇到过这情况
6 1/4/5/6 小张 那也不代表你所说是对的
7 1/4/5/7 小新 这个视情况而定吧
--查询所有父节点
SELECT * FROM comments AS c WHERE '1/4/5/7' LIKE c.path + '%' ;
--查询所有子节点
SELECT * FROM comemnts AS c WHERE c.path LIKE '1/4' + '%' ;

路径枚举也存在一些缺点,比如数据库不能确保路径的格式总是正确或者路径中的节点确实存在。依赖于应用程序的逻辑代码来维护路径的字符串,并且验证字符串的正确性开销很大。无论将varchar 的长度设定为多大,依旧存在长度的限制,因而并不能够支持树结构无限扩展。

3.闭包表

comment_id parent_id author comment
1 0 小明 我不大认同这个观点
2 1 小张 我也不认同
3 2 小红 我同意楼上
4 1 小全 你为什么不认同呢
5 4 小明 我以前遇到过这情况
6 5 小张 那也不代表你所说是对的
7 5 小新 这个视情况而定吧
parent_id son_id
1 1
1 2
1 3
1 4
1 5
1 6
1 7
--查询所有父节点
SELECT c.* FROM comments AS c
    INNER JOIN commentst t on c.son_id = t.son_id
    WHERE t.son_id = 1
--查询所有子节点
SELECT c.* FROM comments AS c
    INNER JOIN commentst t on c.son_id = t.parent_id
    WHERE t.parent_id = 1
--新增节点
INSERT INTO comments(parent_id,son_id)
    SELECT t.parent_id,8
    FROM commentst AS t
    WHERE t.ContentId = 7
    UNION ALL
    SELECT 8,8
--删除节点
DELETE comments WHERE comment_id=8
DELETE commentst WHERE parent_id=8
原文地址:https://www.cnblogs.com/lgxlsm/p/7486412.html