如何在MySQL下的父子模型中计算节点的深度?
我需要深度,除其他外,在我的列表中创建缩进(用PHP编码)。
答案 0 :(得分:2)
这取决于数据库中层次结构的实际实现。如果您使用嵌套集模型( 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上给出适当的索引时,这应该相当快。
这种方法的缺点是你必须在节点移动期间保持节点级别的更新,但是这应该是相当简单和快速的,因为你只对节点本身及其子节点这样做 - 而不是对于大多数表来说你会做嵌套集。
答案 1 :(得分:1)
这可能是一个老问题,但我只是想让其他人知道我几个月前找到了解决方案。我最近在这里写了一下:http://en.someotherdeveloper.com/articles/adjacency-list-model-with-depth-calculation/
答案 2 :(得分:0)
如果您只想复制粘贴,这是我的例子。 我有表项目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 ;