Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/mysql/56.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在MySQL中计算父-子模型中的深度_Mysql_Parent Child_Hierarchy_Depth - Fatal编程技术网

在MySQL中计算父-子模型中的深度

在MySQL中计算父-子模型中的深度,mysql,parent-child,hierarchy,depth,Mysql,Parent Child,Hierarchy,Depth,在MySQL下,如何计算父-子模型中节点的深度 除其他外,我需要在列表中创建缩进的深度(用PHP编码)。这取决于数据库中层次结构的实际实现。如果您使用的是嵌套集模型(),则可以通过单个选择来检索完整的父到子路径 更新:好的,因为您使用的是邻接列表模型,所以我建议将节点级别存储在表中。它不仅可以在一个查询中为您提供节点深度,还可以让您在一个查询中检索到该节点的整个路径(尽管该查询必须动态生成): 由于您知道您的节点位于级别N,因此不需要左连接,并且,如果在id/parent\u id上有适当的索引

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


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

这取决于数据库中层次结构的实际实现。如果您使用的是嵌套集模型(),则可以通过单个选择来检索完整的父到子路径

更新:好的,因为您使用的是邻接列表模型,所以我建议将节点级别存储在表中。它不仅可以在一个查询中为您提供节点深度,还可以让您在一个查询中检索到该节点的整个路径(尽管该查询必须动态生成):

由于您知道您的节点位于级别N,因此不需要左连接,并且,如果在id/parent\u id上有适当的索引,这应该相当快。

这种方法的缺点是,在节点移动期间,您必须保持节点级别的更新,但这应该是相当简单和快速的,因为您只会对节点本身及其子节点进行更新,而不会像对嵌套集那样对大多数表进行更新。

这可能是一个老问题,但我只想让其他人知道,几个月前我找到了一个解决方案。我最近确实在这里写过:

如果你只想复制粘贴,这里是我的例子。 我有ID和父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 ;

是的,我使用过嵌套集,知道如何计算深度,但现在我需要的是父子模型的深度(显然只有列id和父),而不是嵌套集。顺便说一句,我感兴趣的是深度(一个整数),而不是路径。你说的是邻接列表模型。不幸的是,这远远不够理想-您将需要N个select来计算第N个级别上的节点深度。好的,那么您建议我向表中添加另一列,名为depth?但我看不出你在你的例子中使用它。在这种情况下,安全吗?如果可能的话,我更喜欢不改变多行的快速系统。:)在我的示例中,深度为N,您将生成一个包含N个联接的查询。在不预先知道深度的情况下,您必须执行N个查询才能执行相同的操作。如果您碰巧知道整个层次结构的最大可能深度(例如,它不能超过X个级别),另一种可能的折衷方法是使用X个外部联接重写上述查询。它的性能不会很好,但您不必为每个节点保持节点级别。我刚才看到您的另一个问题是:在嵌套集模型中移动节点,看起来您得到了一些非常矛盾的答案,因此我可以理解您的挫折:-)在嵌套集模型中移动节点实际上非常简单(尽管根据您的桌子大小可能会很贵)。如果你还对此感兴趣,请告诉我,我可以添加答案并解释。哈哈,没错,我对此感到非常沮丧。我大约在一周前找到了一个解决方案,我认为应该可行,但还没有实现。但是嵌套集对我来说效果不太好,因为ma可能每天都会有很多更新ny不同的用户,这意味着表中有许多行。出于这个原因,我将给这个邻接列表模型一个快照,它可以安全地移动一个节点。竖起大拇指祝你实现顺利。我更新了我的答案以反映邻接列表模型。
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 ;