3

MySQL の親子モデルでノードの深さを計算するにはどうすればよいですか?

特に、リストにインデントを作成するには、深さが必要です (PHP でコーディングされています)。

4

3 に答える 3

2

これは、データベース内の階層の実際の実装によって異なります。ネストされたセット モデルを使用している場合 (http://mikehillyer.com/articles/managing-hierarchical-data-in-mysql/ ) 単一の選択で完全な親から子へのパスを取得できます。

更新:わかりました。隣接リスト モデルを使用しているので、テーブルにノード レベルを格納することをお勧めします。1 つのクエリでノードの深さを取得できるだけでなく、1 つのクエリでそのノードへのパス全体を取得することもできます (クエリは動的に生成する必要がありますが)。

SELECT n1.name AS lvl1, n2.name as lvl2, n3.name as lvl3, ..., nN.name as lvlN
  FROM nodes AS n1
  JOIN nodes AS n2 ON n2.parent_id = n1.id
  JOIN nodes AS n3 ON n3.parent_id = n2.id
  ...
  JOIN nodes AS nN ON nN.parent_id = n(N-1).id
WHERE nN.id = myChildNode;

ノードがレベル N にあることがわかっているので、左結合の必要はなく、id / parent_id に適切なインデックスがあれば、これはかなり高速になるはずです。
このアプローチの欠点は、ノードの移動中にノード レベルを更新し続ける必要があることですが、テーブルの大部分ではなく、ノード自体とその子に対してのみ行うため、合理的に簡単で高速である必要があります。ネストされたセットを使用します。

于 2009-07-28T18:33:46.077 に答える
0

これは古い質問かもしれませんが、数か月前に解決策を見つけたことを他の人に知らせたいだけです。私は最近それについてここに書きました: http://en.someotherdeveloper.com/articles/adjacency-list-model-with-depth-calculation/

于 2010-11-07T14:04:23.757 に答える
0

ここにコピーペーストするだけの場合は、私の例です。ID および PARENT_ID フィールドを持つテーブル プロジェクトがあります。

DELIMITER $$
DROP FUNCTION IF EXISTS `getDepth` $$
CREATE FUNCTION `getDepth` (project_id INT) RETURNS int
BEGIN
    DECLARE depth INT;
    SET depth=1;

    WHILE project_id > 0 DO
        SELECT IFNULL(parent_id,-1) 
        INTO project_id 
        FROM ( SELECT parent_id FROM Projects WHERE id = project_id) t;

        IF project_id > 0 THEN
            SET depth = depth + 1;
        END IF;

    END WHILE;

    RETURN depth;

END $$
DELIMITER ;
于 2016-02-02T08:38:53.957 に答える