树数据结构的数据库结构


151

在数据库中实现可自定义(即级别数未知的树结构)树数据结构的最佳方法是什么?

在使用带有外键的表之前,我已经做过一次。

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



SQL Server(自2008年起)提供了hierarchyid数据类型
BornToCode

Answers:


80

您提到最常用的实现方法,即邻接表: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在他的书“ Inside Microsoft SQL Server 2005:T-SQL查询”中对最常见的选项进行了很好的概述。

选择模型时要考虑的主要事项是:

1)结构更改的频率-树木的实际结构更改的频率。一些模型提供更好的结构更新特性。但是,将结构更改与其他数据更改区分开来很重要。例如,您可能想为公司的组织结构图建模。某些人将其建模为邻接列表,使用员工ID将员工链接到其主管。这通常是次优的方法。一种通常更有效的方法是将组织结构与员工本身分开建模,并将员工保持为该结构的属性。这样,当员工离开公司时,无需更改组织结构本身,只需更改与离开的员工的联系即可。

2)树是重写入还是重读取-某些结构在读取结构时效果很好,但在写入结构时会产生额外的开销。

3)您需要从结构中获取哪些类型的信息-一些结构擅长提供有关该结构的某些类型的信息。例如,找到一个节点及其所有子节点,找到一个节点及其所有父节点,找到满足特定条件的子节点数,等等。您需要知道从结构中需要什么信息来确定最适合的结构您的需求。


嗨,我正面临与问题中所述完全相同的问题,并想问您一个有关上述主题的问题。考虑到第一主题中的结构(在同一表中引用了ParentId的组织结构化表(非员工结构化表)),我需要设置谁是某个区域的老板。我将直接分配该特定领域的所有员工。您将把那个特定区域的老板放在哪里?在同一个区域内还是上方一个树桩?我的方法是将他/她推荐给上述小组,这给了我更好的结构。谢谢。
Marcos Buarque

1
第一个链接似乎已断开。
豪尔赫·雷涛

极好的答案。谢谢@JeremyDWill!
bobocopy 2014年

56

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

第一种方法是邻接列表模型,该模型实际上就是您要描述的:具有引用表本身的外键。尽管这种方法很简单,但是对于某些查询(如构建整个树)而言,效率可能非常低。

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


您的链接中有一个非常有趣的话题,正在讨论中。谢谢!
Fritz

9

如果您必须使用Relational DataBase来组织树数据结构,则Postgresql具有很酷的ltree模块,该模块提供用于表示存储在分层树状结构中的数据标签的数据类型。您可以从那里得到这个想法。(有关更多信息,请参见:http : //www.postgresql.org/docs/9.0/static/ltree.html

通常,LDAP用于组织层次结构的记录。


2

拥有一张带有外键的桌子对我来说确实很有意义。

然后,您可以在SQL中使用公用表表达式,或者在Oracle中使用connect by before语句来构建树。


我有一个带有LogID标识列的日志表,以及一个带有指向LogID列的FK的ParentLogID列。当写入事务中的第一条日志行时,我抓住了SCOPE_IDENTITY()。所有其他日志记录都使用此值写入ParentLogID列中。这对于将属于一起的行进行分组非常有用。这是查看发生情况的唯一真实方法,如果没有此操作,则将多个事务混合在一起而产生的日志行非常混乱。
KM。

@KM-他说“有道理”而不是“没有道理”
约翰·拉施(John Rasch)2009年



By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.