3

如何在 MySQL 下计算父子模型中节点的深度?

除其他外,我需要在列表中创建缩进的深度(使用 PHP 编码)。

4

3 回答 3

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 上的适当索引,这应该相当快。
这种方法的缺点是您必须在节点移动期间保持节点级别更新,但这应该相当简单和快速,因为您只会对节点本身及其子节点执行此操作 - 而不是对表的大部分你会用嵌套集。

于 2009-07-28T18:33:46.077 回答
0

这可能是一个老问题,但我只想让其他人知道我几个月前找到了解决方案。我最近确实在这里写过:http ://en.someotherdeveloper.com/articles/adjacency-list-model-with-depth-calculation/

于 2010-11-07T14:04:23.757 回答
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 ;
于 2016-02-02T08:38:53.957 回答