+--------------+--------------+------+-----+---------+-------+
| 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个结果。
注意:一个子节点可以有多个父节点
发布于 2018-06-23 16:28:00
在关系数据库中存储树结构的一种聪明方法是使用嵌套集合。
假设我们有以下树:
1
/ \
2 3
/ /\
4 5 6
我们有一个传统的parent_id:
| id | parent_id |
|----+-----------|
| 1 | 0 |
| 2 | 1 |
| 3 | 1 |
| 4 | 2 |
| 5 | 3 |
| 6 | 3 |
在这个模型中,您没有机会,只有递归才能获得某个节点的所有后代。
现在我们为每个节点添加两个数字: left和right。
左边的数字小于所有节点的子节点的数字,而右边的数字大于所有节点的子节点的数字。
我把这些数字放在括号里:
(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 |
现在,您可以使用两个查询来获取节点的所有子节点:首先,您将获得node left和node right,然后:
SELECT
id
FROM
tbl
WHERE
`left` > $node_left
AND
`right` < $node_left
当您修改树的结构时,此方法需要重新计算左侧和右侧。
https://stackoverflow.com/questions/50999160
复制相似问题