2013-01-18 68 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