如何在数据库中存储目录/层次结构/树形结构?

67

如何在数据库中存储目录/层次结构/树形结构?具体来说是MSSQL Server。

@olavk:看起来你没看到我的答案。我使用的方式比递归查询要好得多 :)

p.p.s. 这是正确的方法!


你所倡导的是“实体路径”编码模型。这种方法易于理解,但对于某些操作效率较低,请参见http://vadimtropashko.wordpress.com/2008/08/09/one-more-nested-intervals-vs-adjacency-list-comparison/。 - Troels Arvin
8个回答

24

在SQL数据库中,有许多种存储层次结构的方式。选择哪种取决于您使用的DBMS产品以及数据将如何使用。由于您使用了MSSQL2005标签,我认为您应该开始考虑“相邻列表”模型;如果发现它不适合您的应用程序,则可以查看Vadim Tropashko的比较,重点介绍了不同模型之间的差异,并关注多个性能特征。


8
如果可以使用Sql Server 2008,也许你应该看一下新的 hierarchyid 数据类型。

5

@Ali - 你的链接也坏了! - NightOwl888
@NightOwl888 是的,它已经出现了问题。我刚刚花费了20分钟搜索,但未能找到它...所以我删除了带有损坏链接的评论。 - Ali

3

这更像是我自己的书签,而不是一个问题,但它可能也会对你有所帮助。我使用这篇文章中的方法来在数据库中存储目录/树结构。

文章中还有一些有用的代码片段。

希望这能帮到你。

我与该网站没有任何关联


3
你是否正在使用SQL Server 2005?递归查询使得查询分层数据更加优雅。
编辑:我认为物化路径有点像一个hack。路径包含非规范化冗余数据,你必须使用触发器或其他东西来保持它们的更新。例如,如果一个节点改变了父节点,整个子树必须更新它们的路径。而且子树查询必须使用一些丑陋的子字符串匹配,而不是优雅而快速的连接。

在实现这种解决方案时存在很大的权衡。递归方法曾经是我最喜欢的方法,它很优雅,但效率较低,因为路径必须更频繁地计算。 - izilotti

3
我在我的一个项目中遇到了类似的问题。我们有一个庞大的层次结构,它将永远不断地增加。我需要快速遍历它,然后在完成一些复杂的验证后找到正确的分组。与其去SQL Server纠结如何高效地完成这个任务,当我明确知道递归查询是唯一可行的解决方案时,不如尝试一下Neo4J。它是一个图形数据库,具有许多有用的内置算法,惊人的快速遍历功能以及良好的文档和示例。将层次结构存储在Neo4J中,并使用Thrift服务(或其他方法)访问该层次结构。确实,您需要编写代码来将SQL查询与Neo4J集成,但这将是一种可扩展且更具未来性的解决方案。希望您会发现这很有用。

2
这个问题类似于被关闭的这个问题。我发现对两个问题的答案都对我的追求非常有帮助,最终它们引导我查看了 MongoDB 手册,手册中介绍了 5 种不同的建模树形结构的方法:https://docs.mongodb.com/manual/applications/data-models-tree-structures/
虽然 MongoDB 不是关系型数据库,但所呈现的模型适用于关系型数据库以及其他格式(如 JSON)。你需要根据所列出的优缺点来确定哪种模型最适合你的需求。
这个问题的作者发现了一个解决方案,将父节点和材料化路径模型相结合。保持深度和父节点可能会带来一些问题(额外的逻辑、性能),但某些需求显然具有优势。对于我的项目来说,材料化路径模型最适合我,并通过这篇文章中的技术解决了一些问题(排序和路径长度)。

1

通常的方式是在表中加入一个外键(例如 "ParentId")指向自身。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接