如何递归地从MySQL数据库中获取所有的子程序?

内容来源于 Stack Overflow,并遵循CC BY-SA 3.0许可协议进行翻译与使用

  • 回答 (1)
  • 关注 (0)
  • 查看 (90)
+--------------+--------------+------+-----+---------+-------+
| Field        | Type         | Null | Key | Default | Extra |
+--------------+--------------+------+-----+---------+-------+
| subject      | int(11)      | YES  |     | NULL    |       |
| relationship | varchar(266) | YES  |     | NULL    |       |
| target       | int(11)      | YES  |     | NULL    |       |
+--------------+--------------+------+-----+---------+-------+

如果我有一个ID,我想得到它的子类,我会运行这个查询:

select subject from chebi_obo_relationships where target = %s and relationship="is_a";

这将给我所有的子类的关系'is_a'。然后我想找到所有这些子类的子类。而且我想继续前进,直到没有更多的子类。最后,我想要一个源自我的原始根ID的子ID列表。

有没有一种有效的方法来做到这一点?我尝试了一个python脚本来递归运行上面的查询,生成~100个结果需要几分钟。

提问于
用户回答回答于

在关系数据库中存储树结构的一种智能方法是使用嵌套集。

假设我们有以下树:

    1
   / \
  2   3
 /    /\
4    5  6

我们有一个传统的parent_id:

| id | parent_id |
|----+-----------|
|  1 | 0         |
|  2 | 1         |
|  3 | 1         |
|  4 | 2         |
|  5 | 3         |
|  6 | 3         |

在这个模型中,你没有机会,而是一个递归来获取某个节点的所有后代。

现在我们为每个节点添加2个数字:左边和右边。

左边的数字小于所有节点的子节点的数字,而右边的数字大于所有节点的子节点的数字。

我把这些数字放在括号中:

    (1)     1        (12)
       /            \
 (2)  2 (5)    (6)   3 (11)
     /           /        \
(3) 4 (4)   (7) 5 (8)  (9) 6 (10)

我们得到下表:

| id | parent_id | left | right |
|----+-----------+------+-------|
|  1 |         0 |    1 |    12 |
|  2 |         1 |    2 |     5 |
|  3 |         1 |    6 |    11 |
|  4 |         2 |    3 |     4 |
|  5 |         3 |    7 |     8 |
|  6 |         3 |    9 |    10 |

现在,你可以使用2个查询获取节点的所有子节点:首先,你将节点左侧和节点右侧,然后:

SELECT
    id
FROM
    tbl
WHERE
    `left` > $node_left
AND
    `right` < $node_left

此方法需要在修改树的结构时重新计算左右。

扫码关注云+社区

领取腾讯云代金券