7

How would I go about populating a closure table's depth/length column when inserting a new node to the tree?

The values in ancestor and descendant are IDs from another table that represent pages to be arranged in a tree structure.

Closure Table:

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

This will insert the ancestor and descendants properly but I'm not sure how to populate the depth column Insert Query:

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}';

What's the best way to go about this? Thanks a bunch!

4

2 回答 2

12

将 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;
于 2014-04-17T13:34:35.380 回答
1

这个线程对我帮助很大,但只解决了新的插入,而不是子树的移动。所以我想补充一点,如果你使用交叉连接方法将子树移动到不同的祖先节点,如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>;

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

于 2021-11-05T20:16:26.337 回答