Рассчитайте глубину в модели родительского ребенка в MySQL

StackOverflow https://stackoverflow.com/questions/1195863

Вопрос

Как рассчитать глубину узла в модели родительского ребенка под 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 ;
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top