选择树节点的所有后代

时间:2012-04-27 20:30:27

标签: mysql stored-procedures adjacency-list

我正在使用邻接列表模型在MySQL数据库中存储(非常动态的)树结构。我需要一种方法来选择给定节点的所有后代,最好是通过单次调用存储的例程。我知道嵌套集模型会让这很简单,但它会让其他事情变得非常困难,所以不幸的是它对我来说不是一个选择。这是我到目前为止所得到的:

DELIMITER //

CREATE PROCEDURE get_descendants(node_id INT)
    BEGIN

    DROP TEMPORARY TABLE IF EXISTS descendants;
    CREATE TEMPORARY TABLE descendants (id INT, name VARCHAR(100), parent_id INT);

    INSERT INTO descendants
        SELECT *
        FROM nodes
        WHERE parent_id <=> node_id;

    -- ...?

    END//

DELIMITER ;

这个想法是继续向下钻孔并将孩子们附在下院桌上,直到我到达树叶。然后,我可以从程序外部访问临时表...我希望。 (真的很糟糕,我无法从存储的函数返回结果集。)

我需要以某种方式循环结果并为每一行发出一个新的SELECT语句。我已经读到游标可能在这里有所帮助,但我不知道如何。看起来像游标,你必须预先选择所有内容,然后迭代。

1 个答案:

答案 0 :(得分:0)

最高为read : write。如果你的阅读率非常高,那么建立一个完整的关系表非常有用,而不是临时表。

伪方法(不是真正的代码!):

1. node(1) has child node(2)
     -> Insert a row with (parent_id = 1, child_id = 2, direct = True)

2. node(2) has child node(3)
     -> Insert a row with (parent_id = 2, child_id = 3, direct = True)
     -> Choose all ascendants of node(2)
     -> Ascendants of node(2) : [node(1)]
     -> Insert a row with (parent_id = 1, child_id = 3, direct = False)

3. To retrieve all descendants of node(1)
     -> SELECT child_id FROM [table] WHERE parent_id = 1;

4. To retrieve children of node(1)
     -> SELECT child_id FROM [table] WHERE parent_id = 1 AND direct = True;

5. To retrieve all ascendants of node(3)
     -> SELECT parent_id FROM [table] WHERE child_id = 3;

6. To retrieve parent of node(3)
     -> SELECT parent_id FROM [table] WHERE child_id = 3 AND direct = True;

+-----------+----------+--------+
| parent_id | child_id | direct |
+-----------+----------+--------|
|         1 |        2 | True   |
|         1 |        3 | False  |
|         2 |        3 | True   |
....
+-----------+----------+--------+
Index 1 on ( parent_id, direct )
Index 2 on ( child_id, direct )

这个approche在更新关系时表现不佳。使用风险自负。