3

我有一张名为table. 它有一个以idtype命名的字段INT(11),它代表行的标识符,它还有其他字段,但我认为它们与这个问题无关。

我有另一个名为table_children. 它有一个名为parenttype的字段,INT(11)该字段称为table.id外键。它有另一个以child type命名的字段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所有后代的 's ?0这里的答案是1, 2, 3, 4

感谢您的帮助。

4

3 回答 3

3

使用 MySQL,我这样做的最简单方法是将所有路径存储在树中,创建一个传递闭包

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;

也可以看看:

于 2013-01-18T16:55:37.033 回答
0

由于 MySQL 不是为使用递归查询而设计的,因此我编写了存储过程来处理这个问题。请参阅我的 DBA StackExchange 帖子:查找分层字段的最高级别:有与无 CTE

我写了以下功能

  • GetParentIDByID
  • GetAncestry
  • GetFamilyTree
于 2013-01-18T16:03:32.257 回答
0

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

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

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

但是,如果您愿意更改在 DB 中存储树的方式,还有另一种称为 MPTT(修改的预排序树遍历)的替代方法,它允许您使用单个查询获取整个子树,尽管更新更棘手. 您需要弄清楚插入的额外复杂性是否为您的应用程序带来了良好的折衷,以获得高效检索的好处。

这里有一篇很好的文章解释了 MPTT 。

于 2013-01-18T16:06:55.607 回答