2010-08-02 134 views
3

最佳做法,我會盡力揭露儘可能明確;)DB設計:分層結構

嗯,我需要存儲一些數據可以linket以自己爲父母>孩子的關係,沒有 - 極限深度。

我的第一個嘗試是:

entry_id | parent_id | value 
    1 | NULL | Foo //foo is the grand parent 
    2 | 1  | Bar //bar is child of Foo 
    3 | 1  | Baz //baz too 
    4 | 2  | Bho //bho is child of Bar 
    5 | 4  | Som //som is child of Bho 
    6 | NULL | Git //another grand parent 
    7 | 6  | Tim //Git's child 

..和等。

這個結構的工作原理,但它是不可能的(或至少,我不能通過)找到所有的Foo孩子和'子孩子'只有一個查詢..這需要一個循環。

我的目標是有一個結構SELECT查詢優化,可以給我一個鏡頭的所有關係,是這樣的:

SELECT "ALL SONS OF Bar" 

輸出:

entry_id | parent_id | value 
    1  | NULL | Bar 
    4  | 2  | Bho 
    5  | 4  | Som 

但這種結構犯規似乎讓我這樣做。

有什麼想法?

如果能夠決定的事情,我會在PostgreSQL上運行(我想用數組字段類型,但查詢不會有太大的快)

編輯爲菲利普評論:在我的具體的數據不應該更改太頻繁,但我可能需要將此結構用於其他類似的任務 - 但不是相同的 - 數據可以更新很多次。

作爲一個側面說明,使用外鍵(或類似的行爲)將是最好的(刪除一個「父親」應該刪除所有孩子的 - 無孤兒被允許)

+0

數據多久會發生變化,以及它將如何變化(添加葉子,交換分支,從中間刪除節點/處理孤兒等等)。更簡單的系統可以允許快捷方式,但如果您需要嚴格的靈活性,事情會變得棘手。 – 2010-08-02 18:25:10

+1

值0是錯誤的,沒有這個值的entry_id:任何外鍵約束都會失敗。沒有父母時使用NULL。 – 2010-08-02 19:15:34

+0

@frank:你說得對。 – Strae 2010-08-02 21:02:11

回答

10

我認爲你會從閱讀中受益Managing Hierarchical Data in MySQL。它講述瞭如何將一張桌子變成一個只有幾個屬性和一些家務的層次結構。即使你不打算這樣做,這是有見地的。

對於PostgreSQL,您可以使用WITH RECURSIVE查詢:WITH Queries (Common Table Expressions)
您至少需要8.4版才能使用它們。

+1

+1 WITH RECURSIVE功能。 – rfusca 2010-08-02 17:57:43

4

比爾Karwin取得了約分層數據一個不錯的幻燈片:

http://www.slideshare.net/billkarwin/models-for-hierarchical-data

正如JMZ已經說過,遞歸查詢是一個真正的問題解決者。

+1

如果您觀看幻燈片,請特別注意嵌套集模型。另請注意,鄰接表是您的設計。 – 2010-08-03 12:09:19