MySQL所有父子关系

时间:2013-01-18 15:51:39

标签: mysql hierarchical-data

我有一个名为table的表。它有一个名为id的字段,类型为INT(11),代表行的标识符,它有其他字段,但我不认为它们与此问题相关。

我有另一个名为table_children的表。它有一个名为parent且类型为INT(11)的字段,它将table.id称为外键。它有另一个名为child且类型为INT(11)的字段,它也将table.id称为外键。此表描述了table行到table行父子关系。

这是一个可能的设置。

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

如何在最少数量的请求中获取id的所有后代的0?这里的答案是1234

感谢您的帮助。

3 个答案:

答案 0 :(得分: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;

另见:

答案 1 :(得分:0)

由于MySQL不是设计用于递归查询,我编写了存储过程来处理这个问题。请参阅我的DBA StackExchange帖子:Find highest level of a hierarchical field: with vs without CTEs

我写了以下函数

  • GetParentIDByID
  • GetAncestry
  • GetFamilyTree

答案 2 :(得分:0)

通过当前设置数据的方式,可以有效地获取所有后代。你会查询这样的东西:

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

其中x,y和z是上一次迭代中检索到的所有孩子。重复查询,直到没有更多行。这将需要与树的深度一样多的查询。

但是,如果您愿意更改将树存储在数据库中的方式,则还有另一种称为MPTT(修改的预订树遍历)的替代方法,它允许您使用单个查询获取整个子树,尽管更新比较棘手。您需要弄清楚插入的额外复杂性是否为您的应用程序提供了良好的权衡,以获得有效检索的优势。

有一篇很好的文章解释了MPTT here