树型数据结构的数据库结构

在数据库中实现可定制的树形数据结构(意思是,具有未知数目级别的树形结构)的最佳方法是什么?

在使用具有自身外键的表之前,我已经这样做过一次。

您还可以看到其他哪些实现,这个实现是否有意义?

175125 次浏览

看看 管理 MySQL 中的层次数据,它讨论了在关系数据库中存储和管理分层(树状)数据的两种方法。

第一种方法是邻接列表模型,它实际上就是您所描述的: 拥有一个引用表本身的外键。虽然这种方法很简单,但是对于某些查询(比如构建整棵树)来说效率非常低。

本文讨论的第二种方法是嵌套集模型。这种方法更加有效和灵活。有关详细说明和示例查询,请参阅本文。

对于我来说,拥有一个自身具有外键的表是有意义的。

然后,可以使用 SQL 中的公共表表达式或 Oracle 中的 connect by 前面语句来构建树。

您提到的最常用的实现是邻接列表: Https://blogs.msdn.microsoft.com/mvpawardprogram/2012/06/25/hierarchies-convert-adjacency-list-to-nested-sets

还有其他模型,包括物化路径和嵌套集: Http://communities.bmc.com/communities/docs/doc-9902

Joe Celko 已经写了一本关于这个主题的书,从一般 SQL 的角度来看,这是一个很好的参考(在上面的嵌套文章链接中提到过)。

而且,Itzik Ben-Gann 在他的书《 Microsoft SQL Server 2005: T-SQL 查询》中对最常见的选项有一个很好的概述。

在选择模式时需要考虑的主要因素是:

1)结构变化的频率-树的实际结构变化的频率。一些模型提供了更好的结构更新特性。但是,将结构更改与其他数据更改分开很重要。例如,您可能希望对公司的组织结构图进行建模。有些人会将其建模为邻接列表,使用员工 ID 将员工与主管联系起来。这通常是次优方法。一种更好的方法是将组织结构与员工本身分开建模,并将员工作为结构的一个属性。这样,当员工离开公司时,组织结构本身不需要改变,只需要与离开的员工建立联系。

2)树状结构在读取结构时工作得非常好,但是在写入结构时会产生额外的开销。

3)你需要从这个结构中获得哪些类型的信息——有些结构擅长提供关于这个结构的某些类型的信息。例如,查找一个节点及其所有子节点,查找一个节点及其所有父节点,查找满足某些条件的子节点的计数,等等。您需要知道从结构中需要什么信息,以确定最适合您需要的结构。

如果你必须使用关系数据库来组织树型数据结构,那么 Postgreql 有一个很酷的 ltree 模块,它提供数据类型来表示存储在树型结构中的数据的标签。你可以从那里得到想法。(有关详细信息,请参阅: http://www.postgresql.org/docs/9.0/static/ltree.html)

通常 LDAP 是用来组织层次结构的记录。

如果任何使用 MSSQLServer2008及以上版本的人遇到这个问题: SQLServer2008或更高版本有一个专门为此任务设计的新的“层次结构 ID”特性。

更多信息请访问 https://learn.microsoft.com/en-us/sql/relational-databases/hierarchical-data-sql-server