Domanda

Come faccio a calcolare la profondità di un nodo in un modello padre-figlio in MySQL?

Ho bisogno della profondità, tra le altre cose, creare il trattino nella mia lista (codificato con PHP).

È stato utile?

Soluzione 2

Questa potrebbe essere una vecchia questione, ma voglio solo far sapere agli altri che ho trovato una soluzione qualche mese fa. Recentemente ho scritto su di esso qui: http: // it. someotherdeveloper.com/articles/adjacency-list-model-with-depth-calculation/

Altri suggerimenti

Questo dipende l'effettiva attuazione della gerarchia nel database. Se si utilizza nidificato set modello ( http://mikehillyer.com/articles/managing-hierarchical-data-in-mysql/ ) è possibile recuperare il percorso completo genitore a figlio attraverso un unico select.

Aggiorna : Ok, dal momento che si sta andando con il modello di lista di adiacenza suggerisco di memorizzare livello di nodo nella tabella. Non solo vi darà la profondità del nodo in una query, ma permetterà anche di recuperare l'intero percorso a quel nodo in una query (anche se quella domanda avrebbe dovuto essere generato dinamicamente):

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;

Dal momento che si sa che il nodo è a livello N non c'è bisogno di sinistra si unisce e, data indici appropriati sul id / parent_id questo dovrebbe essere ragionevolmente veloce.
L'aspetto negativo di questo approccio è che si dovrà tenere livello di nodo aggiornato durante nodo si muove, ma che dovrebbe essere abbastanza semplice e veloce come si farebbe farlo solo per il nodo stesso e dei suoi figli - non per la maggior parte della tabella come si farebbe con i set nidificati.

Se si desidera solo per copia incolla qui è il mio esempio. Ho Progetti tavolo con ID e parent_id Campi.

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 ;
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top