【问题标题】:MySQL all parent-child relationshipsMySQL所有的父子关系
【发布时间】:2013-01-19 00:55:37
【问题描述】:

我有一个名为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

如何以最少的请求数获得0 的所有后代的id?这里的答案是1234

感谢您的帮助。

【问题讨论】:

    标签: mysql hierarchical-data


    【解决方案1】:

    使用 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;
    

    另见:

    【讨论】:

    • 我会选择这个。这对我来说似乎很有效,因为此表是经过预处理的,并且在运行时只执行一个查询。
    【解决方案2】:

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

    我写了以下函数

    • GetParentIDByID
    • GetAncestry
    • GetFamilyTree

    【讨论】:

      【解决方案3】:

      根据您当前的数据设置方式,有一种获取所有后代的有效方法。你会这样查询:

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

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

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

      有一篇很好的文章解释了MPTThere

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2019-11-22
        • 1970-01-01
        • 1970-01-01
        • 2018-10-03
        • 2012-01-27
        • 1970-01-01
        • 1970-01-01
        • 2011-01-31
        相关资源
        最近更新 更多