一段时间以来,我一直在思考如何最好地处理 SQL 中的层次结构。由于邻接列表的局限性和 MPTT/嵌套集的复杂性,我开始考虑简单地将关键路径存储为一个简单的node_key/node_key/...
字符串。我决定整理一下这三种技术的优缺点:
创建/删除/移动节点所需的调用次数:
- 邻接 = 1
- MPTT = 3
- Path = 1(将旧节点路径替换为包含该路径的所有节点的新节点路径)
获取树所需的调用次数:
- 邻接 = [子级别数]
- MPTT = 1
- 路径 = 1
获取节点/祖先路径所需的调用次数:
- 邻接 = [超层数]
- MPTT = 1
- 路径 = 0
获取子节点数量所需的调用次数:
- 邻接 = [子级别数]
- MPTT = 0(可以从右/左值计算)
- 路径 = 1
获取节点深度所需的调用次数:
- 邻接 = [超层数]
- MPTT = 1
- 路径 = 0
需要的数据库字段:
- 邻接 = 1(父)
- MPTT = 3(父、右、左)
- 路径 = 1(路径)
结论
存储路径技术在每个用例中都使用与其他技术相同或更少的调用,除了一个。通过这种分析,存储路径显然是赢家。更不用说,它实现起来要简单得多,人类可读等等。
所以问题是,存储路径不应该被认为是比 MPTT 更强大的技术吗?为什么存储路径不是一种更常用的技术,为什么您不在给定实例中通过 MPTT 使用它们?
另外,如果您认为此分析不完整,请告诉我。
更新:
以下是 MPTT 可以开箱即用的至少 2 件存储路径解决方案无法做到的事情:
- 允许计算每个节点的子节点计数,而无需任何额外的查询(如上所述)。
- 对给定级别的节点施加命令。其他解决方案是无序的。