Рассчитайте глубину в модели родительского ребенка в MySQL
-
20-09-2019 - |
Вопрос
Как рассчитать глубину узла в модели родительского ребенка под MySQL?
Мне понадобится глубина, чтобы, среди прочего, создать отступ в моем списке (кодировано с PHP).
Решение 2
Это может быть старый вопрос, но я просто хочу, чтобы другие знали, что я нашел решение несколько месяцев назад. Я недавно написал об этом здесь: http://en.someotherdeveloper.com/articles/adjacency-list-model-with-depth-calculation/
Другие советы
Это зависит от фактической реализации вашей иерархии в базе данных. Если вы используете модель вложенных наборов (http://mikehillyer.com/articles/managing-hierarchical-data-in-mysql/) Вы можете получить полный путь от родителей до детей через один выбор.
Обновлять: ОК, так как вы собираетесь с моделью списка смежности, я предлагаю сохранить уровень узлов в таблице. Он не только даст вам глубину узла в одном запросе, но также позволит вам получить весь путь к этому узлу в один запрос (хотя запрос должен быть динамически генерироваться):
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, это должно быть достаточно быстро.
Недостатком этого подхода является то, что вам придется обновлять уровень узлов во время движений узлов, но это должно быть достаточно простым и быстро Вы бы делали с вложенными наборами.
Если вы хотите просто скопировать вставку, вот мой пример. У меня есть табличные проекты с подачами 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 ;