2009-02-25 54 views
7

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

节点表

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

祖先表

NodeId int 
AncestorId int 
Hops int 

上的NodeId,AncestorId指数,啤酒花

表是这样的:

节点表

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 

它也是e asy以获得直接的孩子以及

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

我很想知道你可能用于这种类型的东西的其他解决方案。根据我的经验,层次结构可能变得非常多毛,任何优化检索的方法都非常重要。

回答

4

正如MarkusQ和n8wrl已经指出,乔·塞科有一些这方面的好东西。我只是补充说,有多种方法来建模一个层次结构(Joe的书包含了我相信的几个,而不仅仅是他认为最好的一个)。您的最终决定有望考虑到您自己的特定需求。对其进行建模的一些不同方式对写入密集型操作来说更好,而其他方式则更适合频繁或快速读取层次结构。只要记住你的系统将如何处理它。

10

有一些特定供应商的扩展要做到这一点,但我最喜欢的DB-中立的方式来自乔·塞科 - 谷歌的乔·塞科树木和层次结构“或买这本书:link text

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

6

您可能还需要检查出的 “嵌套集合” 模式:

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

或者你可以谷歌更多。

P.S .: Curses,n8wrl,你输入的比我快!

+0

嵌套集合!这是我期待的术语! – n8wrl 2009-02-25 19:51:12

+0

非常有趣的文章。我总是遇到的一个问题是添加/删除节点时,必须更新其后每个节点的位置。 – 2009-02-25 20:13:32

1

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