2009-02-25 52 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中,可以使用遞歸調用自身的存儲過程。