7

我很想知道在数据库设计方面处理层次结构的最佳方法(最佳实践)是什么。这是我通常如何处理它们的一个小例子。

节点表

NodeId int PRIMARY KEY
NodeParentId int NULL
DisplaySeq int NOT NULL
Title nvarchar(255)

祖先表

NodeId int
AncestorId int
Hops int

在 NodeId、AncestorId、Hops 上有索引

表如下所示:

节点表

NodeId    NodeParentId    DisplaySeq    Title
1         NULL            1             'Root'
2         1               1             'Child 1'
3         1               2             'Child 2'
4         2               1             'Grandchild 1'
5         2               2             'Grandchild 2'

祖先表

NodeId    AncestorId    Hops
1         NULL          0
1         1             0
2         1             1
2         2             0
3         1             1
3         3             0
4         1             2
4         2             1
4         4             0
5         1             2
5         2             1
5         5             0

通过这种设计,我发现对于大型层次结构,通过加入 AncestorId = 目标 NodeId 的祖先表,我可以非常快速地获得整个层次结构部分,例如:

SELECT *
FROM Node n
INNER JOIN Ancestor a on a.NodeId=n.NodeId
WHERE a.AncestorId = @TargetNodeId

获得直子也很容易

SELECT *
FROM Node n
INNER JOIN Ancestor a on a.NodeId=n.NodeId
WHERE a.AncestorId = @TargetNodeId
AND Hops = 1

我很想知道您可能为此类事情使用了哪些其他解决方案。以我的经验,层次结构可能会变得非常复杂,任何优化它们的检索的方法都非常重要。

4

6 回答 6

10

有一些特定于供应商的扩展可以做到这一点,但我最喜欢的 db-neutral 方式来自 Joe Celko - google 'Joe Celko Trees and Hierarchies' 或购买这本书:链接文本

这是一个非常聪明的基于集合的方法。易于查询层次结构。我添加了您拥有的“parentID”字段,因为我问了很多“直接孩子”和“父母”问题,这加快了速度。但这是获取“祖先”或“后代”查询的好方法。

于 2009-02-25T19:43:37.253 回答
6

您可能还想查看“嵌套集”模式:

http://www.intelligententerprise.com/001020/celko.jhtml (断开的链接)

或者你可以谷歌了解更多。

PS:诅咒,n8wrl,你打字比我快!

于 2009-02-25T19:44:05.287 回答
4

正如 MarkusQ 和 n8wrl 已经指出的那样,Joe Celko 在这方面有一些好东西。我只想补充一点,有多种方法可以对层次结构进行建模(Joe 的书中包含我相信的几种方法,而不仅仅是他认为“最好的”一种)。希望您的最终决定会考虑到您自己的具体需求。一些不同的建模方法更适合写入密集型操作,而另一些更适合频繁或快速读取层次结构。请记住您的系统将使用它做什么。

于 2009-02-25T19:48:17.337 回答
2

SQL Server 2008 引入了hierarchyid 数据类型

于 2009-02-25T19:47:20.410 回答
1

在 Oracle 中,您可以使用 CONNECT BY/START WITH 来查询层次结构数据。在 SQL Server 中,您可以使用递归调用自身的存储过程。

于 2009-02-25T19:44:42.367 回答
1

我肯定会推荐嵌套集。他们都是伟大的。

http://threebit.net/tutorials/nestedset/tutorial1.html http://www.dbmsmag.com/9603d06.html

于 2009-02-25T20:34:56.553 回答