2

我正在使用邻接列表模型在 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 语句。我读过游标在这里可能会有所帮助,但我不知道如何。似乎使用游标您必须预先选择所有内容,然后进行迭代。

4

1 回答 1

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 )

这种方法在更新关系时性能很差。使用风险自负。

于 2012-06-08T00:08:39.053 回答