【问题标题】:Depth in MYSQL and Closure Table TreesMYSQL 和闭包表树的深度
【发布时间】:2014-04-12 13:03:35
【问题描述】:

在向树中插入新节点时,我将如何填充闭包表的深度/长度列?

祖先和后代中的值是来自另一个表的 ID,表示要以树结构排列的页面。

闭包表:

ancestor    descendant     depth
1               1            0
1               2            1
1               3            1 
1               4            1
2               2            0
3               3            0 
4               4            0

这将正确插入祖先和后代,但我不确定如何填充深度列 插入查询:

INSERT INTO closure_tree_path (ancestor, descendant)
SELECT ancestor, '{$node_id}' FROM closure_tree_path
WHERE descendant = '{$parent_id}'
UNION ALL SELECT '{$node_id}', '{$node_id}';

解决此问题的最佳方法是什么?非常感谢!

【问题讨论】:

    标签: php mysql transitive-closure-table


    【解决方案1】:

    将 depth+1 添加到第一个 SELECT。

    INSERT INTO closure_tree_path (ancestor, descendant, depth)
    SELECT ancestor, '{$node_id}', depth+1 FROM closure_tree_path
    WHERE descendant = '{$parent_id}'
    UNION ALL SELECT '{$node_id}', '{$node_id}', 0;
    

    【讨论】:

    • 我在 SQL fiddle 中尝试过,它看起来工作正常吗? (减去最后附加的缺失“0”)。应该从一开始就把它放在小提琴中去捕捉所有的错误。 sqlfiddle.com/#!2/c06b3/1
    【解决方案2】:

    这个帖子对我帮助很大,但只解决了新的插入问题,而不是子树移动。所以我想我要补充一点,如果你使用交叉连接方法将子树移动到不同的祖先节点,如 SQL Antipatterns 书中所述,并且你需要计算深度,你会想要做它是这样的:

    (这假设您已经执行了删除查询,以删除这个即将被移动的子树的先前祖先的路径。)

    INSERT INTO closure_tree_path (ancestor, descendant, depth)
      SELECT supertree.ancestor, subtree.descendant, supertree.depth + subtree.depth + 1
      FROM closure_tree_path AS supertree
        CROSS JOIN closure_tree_path AS subtree
      WHERE supertree.descendant = <new parent node ID>
        AND subtree.ancestor = <node ID to move>;
    

    这应该保留子树的深度(不会改变),并且会正确地重新计算所有新祖先路径的正确深度。

    【讨论】:

      猜你喜欢
      • 2015-10-11
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-04-08
      • 2011-02-15
      • 1970-01-01
      • 2016-10-18
      • 1970-01-01
      相关资源
      最近更新 更多