日期:2014-05-17  浏览次数:20513 次

SQL 反模式 第三章:单纯的树 使用闭包集解决问题的疑问
最近在看SQL 反模式这本书 其中有节单纯的树 感觉挺有意思  

 书中部分摘要
第三章:单纯的树
  目标:分层存储和查询 案例:文章和评论 每篇文章有多篇评论,每个评论可以引用另外的评论。

反模式: 最简单的解决方案就是在同一张表中存储该评论id的父节点id(parent_id) 但是这样只能查询两层的数据。如果需要三级,四级,则必须使用更多的邻接表,这种查询当然就无法直接树的无限级扩展了。查询一棵完整的树数据或者评论总数之类的会导致查询数据库的冗余数据。使用邻接表增加更新非常方便,但是删除就涉及到级联了

.....................


 3.闭包集:重新用一张treepath表来存储树中所有节点的关系。里面有两个字段(ancestor,descendant)来存储祖先-后代关系,包括不是直接的父子关系信息。



我在项目中尝试这种方式 发现有一个功能不好取 
就是取出所有顶级分类的菜单
传统的反模式  只要  select * from [menu] where parent_id =0 
麻烦大神帮忙看看 比如下列参考数据 目的要取出ID 是1 和5的顶级菜单
============================================

id   name    
1    顶级菜单1
2     二级分类1
3     二级分类2
4      三级子分类1
5    顶级菜单2
6     二级分类3

treepath 闭包表
Ancestor Descendant  PathLength
1             1          0
1             2          1
1             3          1
1             4          2
2             2          0
3             3          0
3             4          1
4             4          0
5             5          0
5             6          1
6             6          0 
============================================



               

------解决方案--------------------
select * from treepath t where  not exists
(
select 1 from treepath where Ancestor<>t.Ancestor and Descendant=t.Descendant
)