2

隣接リストモデルを使用して、(非常に動的な)ツリー構造をMySQLデータベースに格納しています。特定のノードのすべての子孫を選択する方法が必要です。できれば、保存されたルーチンを1回呼び出すだけです。入れ子集合モデルはこれを簡単にすることは知っていますが、他のことは非常に難しくなるので、残念ながらそれは私にとって選択肢ではありません。これが私がこれまでに得たものです:

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 に答える