Как да изчисля дълбочината на възел в модел родител-дете под MySQL?
Ще ми трябва дълбочината, наред с други неща, за да създам отстъпа в моя списък (кодиран с PHP).
Как да изчисля дълбочината на възел в модел родител-дете под MySQL?
Ще ми трябва дълбочината, наред с други неща, за да създам отстъпа в моя списък (кодиран с PHP).
Това зависи от действителното внедряване на вашата йерархия в базата данни. Ако използвате модел на вложени набори (http://mikehillyer.com/articles/managing-hierarchical-data-in-mysql/ a>) можете да извлечете пълния път от родител до дете чрез едно избиране.
Актуализация: Добре, тъй като ще използвате модел на списък със съседство, предлагам да съхранявате ниво на възел в таблицата. Не само ще ви даде дълбочината на възела в една заявка, но също така ще ви позволи да извлечете целия път до този възел в една заявка (въпреки че тази заявка трябва да бъде динамично генерирана):
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 това трябва да е сравнително бързо.
Недостатъкът на този подход е, че ще трябва да поддържате нивото на възел актуализирано по време на преместване на възел, но това трябва да е сравнително лесно и бързо, тъй като бихте го направили само за самия възел и неговите деца - не за по-голямата част от таблицата, както бихте направили с вложени набори.
Това може да е стар въпрос, но просто искам да уведомя другите, че намерих решение преди няколко месеца. Наскоро писах за това тук: http://en.someotherdeveloper.com/articles/adjacency-list-model-with-depth-calculation/
Ако искате просто да копирате и поставите, ето моят пример. Имам таблични проекти с полета 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 ;