2013-01-18 98 views
2

我有一個名爲table的表。它有一個名爲id的字段,其類型INT(11)代表行的標識符,它有其他字段,但我不認爲它們與此問題相關。我有另一個表table_children。它有一個名爲parent的字段,其類型INT(11)table.id作爲外鍵。它有另一個字段child,其類型INT(11)也指table.id作爲外鍵。此表描述了table行到table行父子關係。MySQL的所有親子關係

這是一個可能的設置。

table table_children 
id  parent child 
0  0  1 
1  1  2 
2  1  3 
3  3  4 
4 

我怎樣才能得到的0所有後代的id的請求中數量最少?這裏的答案是1,2,3,4

謝謝你的幫助。

回答

2

使用MySQL,我這樣做的最簡單方法是在樹中存儲所有路徑,創建一個transitive closure

table_children 
parent child 
0  0 
1  1 
2  2 
3  3 
4  4 
0  1 
0  2 
0  3 
0  4 
1  2 
1  3 
1  4 
3  4 

現在你可以這樣進行查詢:

SELECT t.* 
FROM table_children c 
JOIN table t ON c.child = t.id 
WHERE c.parent = 0; 

參見:

+0

我將與此一起去。這對我來說似乎很有效,因爲這個表是預處理的,並且在運行時只執行一個查詢。 – Numid

0

與您的數據是目前設置的方式,有有效的方式來獲得所有的後代。你可以這樣查詢:

SELECT child FROM table_children WHERE parent in (x, y, z); 

其中x,y和z都是前一次迭代中檢索到的子數據。重複查詢,直到你沒有更多的行。這將花費與樹的深度一樣多的查詢。然而,如果您打算改變將數據樹存儲在數據庫中的方式,還有另一種稱爲MPTT(Modified Pre-order Tree Traversal)的替代方案,它允許您使用單個查詢獲取整個子樹,儘管更新比較棘手。你需要弄清楚是否額外的複雜性爲你的應用程序插入一個良好的折衷方案,以獲得有效檢索的好處。

有一篇很好的文章解釋MPTT here