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