管理SQL中的层次结构:MPTT /嵌套集与邻接列表对存储路径

前端之家收集整理的这篇文章主要介绍了管理SQL中的层次结构:MPTT /嵌套集与邻接列表对存储路径前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
一段时间以来,我一直在摔跤如何最好地处理sql中的层次结构.受到邻接列表的限制和MPTT /嵌套集的复杂性的沮丧,我开始考虑简单地存储关键路径,而不是简单的node_key / node_key / …字符串.我决定编制三种技巧的利弊:

创建/删除/移动节点所需的呼叫数:

>邻接= 1
> MPTT = 3
> Path = 1(将旧节点路径替换为包含该路径的所有节点的新节点路径)

获取树所需的通话次数

> Adjacency = [子级数]
> MPTT = 1
> Path = 1

获取节点/祖先路径所需的呼叫数:

> Adjacency = [超级数]
> MPTT = 1
> Path = 0

获取子节点数所需的呼叫数量

> Adjacency = [子级数]
> MPTT = 0(可以从右/左值计算)
> Path = 1

获取节点深度所需的呼叫数:

> Adjacency = [超级数]
> MPTT = 1
> Path = 0

需要DB字段:

> Adjacency = 1(parent)
> MPTT = 3(父,右,左)
> Path = 1(路径)

结论

存储的路径技术在除了一个用例之外使用与其他技术相同或更少的调用.通过这种分析,存储路径是一个明显的赢家.更不用说,实现起来要简单得多,人性化等等

所以问题是,不应该将存储的路径视为比MPTT更强大的技术?为什么存储的路径不是更常用的技术,为什么不能在给定的实例中使用MPTT?

另外,如果你认为这个分析是不完整的,请让我知道.

更新:

这里至少有两件事情,MPTT可以开箱即用,存储的路径解决方案不会:

>允许计算每个节点的子节点数,而不需要任何其他查询(如上所述).
>在给定级别的节点上施加命令.其他解决方案是无序的.

解决方法

您也可以考虑我在 What is the most efficient/elegant way to parse a flat table into a tree?的答案中描述的Closure Table设计

创建/删除/移动节点所需的呼叫:

>关闭= 1

要求获取树的通话:

>关闭= 1

获取路径到节点/祖先所需的呼叫:

>关闭= 1

需要拨打电话才能获得子节点数:

>关闭= 1

获取节点深度所需的呼叫:

>关闭= 1

需要DB字段:

> Adjancency = 1个字段/行
> Path = 1 more field / row
> MPTT = 2或3个以上的字段/行
> Closure =额外表中的2或3个字段.该表具有O(n ^ 2)行最差的情况,但远远少于大多数实际情况.

还有几个其他的考虑:

支持无限深度:

> Adjacency = yes
> MPTT =是
> Path = no
>关闭=是

支持引用完整性:

> Adjacency = yes
> MPTT =否
> Path = no
>关闭=是

我也在我的演讲Models for Hierarchical Data with SQL and PHP和我的书,SQL Antipatterns: Avoiding the Pitfalls of Database Programming中的封面表.

猜你在找的MsSQL相关文章