2016-11-28 73 views
1

我試圖設計一個具有金字塔關係的數據庫。例如,這是我的數據:實現圖樹的最佳數據庫結構

enter image description here

好了,我怎麼都可以存儲這些數字,並保持它們之間的關係?


目前我是這樣做的:

// myTree 
+----+------+--------+ 
| id | node | parent | 
+----+------+--------+ 
| 1 | 8 | Null | 
| 2 | 10 | 8  | 
| 3 | 3 | 8  | 
| 4 | 14 | 10  | 
| 5 | 6 | 3  | 
| 7 | 1 | 3  | 
| 8 | 13 | 14  | 
| 9 | 7 | 6  | 
| 10 | 4 | 6  | 
+----+------+--------+ 

但在這種情況下,我只能通過一個查詢選擇一個圖形的水平。雖然我需要選擇一個節點的整個分支。敵人examle:

$node = 14; 

預期結果:

[8, 10, 14, 13] 

注:節點是唯一的。

無論如何,我怎樣才能設計數據庫,使其通過一個查詢訪問所有級別?

+1

點擊此鏈接管理MySQL中的分層數據http://mikehillyer.com/articles/managing-hierarchical-data-in-mysql/ –

+0

這是一個常見問題解答。請谷歌您的標題。 – philipxy

+0

升級到MySQL 8.0或MariaDB 10.2,以便您可以使用遞歸CTE。 –

回答

1

如果你在必須在MySQL中做,@philipxy提供了一個很好的鏈接,但是你應該知道MySQL對於層次/樹數據來說是一個糟糕的選擇。
其他DBMS如Oracle,SQL Server和PostgreSQL對於鄰接表方法來說更好一些,因爲它們至少支持迭代(「遞歸」)查詢。
爲了一個合適的,我建議你會看看neo4j

+0

我很高興你採納了我的意見,其精神在於它的意思:) – onedaywhen

0

你的數據庫設計是正確的,唯一的挑戰是如何從單個查詢你得到所有的子節點。爲此,您可以編寫用戶定義的函數並從查詢中調用該函數。內部函數可以編寫分層查詢或數據庫特定的代碼,並沒有太大的區別,因爲這個函數只能從查詢中調用。

1

你可能想看看nested sets。在實際嘗試工作系統之前,我已經知道這種技術很長時間了,主要是因爲很少有人寫這篇文章是積極的。我對使用鄰接列表或任何其他方法查詢圖形信息的複雜性感到驚喜。

但是,它有缺點,使它在非常特定的環境中很有用:列表必須是靜態的。也就是說,一旦創建完成,列表本身的維護就很少 - 節點相對於彼此的移動,新節點的添加或現有節點的刪除。這是因爲每一行都依賴於其他行(這取決於其他行,等等)。列表中的更改可能涉及更新列表中的所有條目。對於一個小小的變化,這是一個很大的努力。

我有一個完美的使用案例:所有州,哥倫比亞特區和美國領土的教育標準。教育標準每年最多改變一次,大多數州的改變次數少於此次數。無論如何,一旦學年開始,當時有效的標準在此期間仍然有效。所以一旦年初的名單建立起來,直到明年年初纔會有所改變。

想象一下,能夠查詢僅包含在樹的任何節點的子樹中的信息。絕對的powah!

還有其他的好處,我從來沒有得到實施,如學校目錄,也經過了非常小的變化,一旦學期開始。

通過「更改」請注意,我指的是操縱樹結構的更改:插入新節點,將節點從一個位置移動到另一個位置,移除節點等。更新節點的內容是不是有問題。

另外請注意,我有幾個星期來玩弄熟悉結構。您可以編寫一些激進的查詢,但需要一段時間才能熟悉系統。

它現在可能不適合您的需求,但對於何時可能會變得有用會得到基本的瞭解並不會造成什麼影響。這是一個無法忽視的結構。