Question

Comment puis-je calculer la profondeur d'un nœud dans un modèle parent-enfant sous MySQL?

Je vais avoir besoin de la profondeur, entre autres, créer le tiret dans ma liste (avec code PHP).

Était-ce utile?

La solution 2

Cela peut être une vieille question, mais je veux juste faire savoir aux autres que j'ai trouvé une solution il y a quelques mois. Je ne récemment écrire à ce sujet ici: http: // fr. someotherdeveloper.com/articles/adjacency-list-model-with-depth-calculation/

Autres conseils

Cela dépend de la mise en œuvre effective de votre hiérarchie dans la base de données. Si vous utilisez modèle des ensembles imbriqués ( http://mikehillyer.com/articles/managing-hierarchical-data-in-mysql/ ), vous pouvez récupérer le chemin complet à l'enfant parent par l'intermédiaire d'une seule sélection.

Mise à jour : Ok, puisque vous allez avec le modèle de liste contiguïté Je suggère de stocker le niveau de noeud dans la table. Non seulement il vous donnera la profondeur de noeud dans une requête, mais il vous permettra également de récupérer le chemin complet vers ce noeud dans une requête (bien que cette requête devrait être générée dynamiquement):

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;

Puisque vous savez que votre noeud est au niveau N il n'y a pas besoin de gauche rejoint et, compte tenu des index appropriés sur id / PARENT_ID cela devrait être assez rapide.
L'inconvénient de cette approche est que vous devez garder le niveau de nœud mis à jour lors de mouvements de noeud, mais cela devrait être assez simple et rapide que vous ne le faire pour le nœud lui-même et ses enfants - pas pour la majorité de la table vous le feriez avec des ensembles imbriqués.

Si vous voulez juste copier coller est mon exemple ici. Je Projets de table avec ID et PARENT_ID fileds.

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 ;
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top