在巢狀集模型中改變節點的父親節點
阿新 • • 發佈:2019-12-31
什麼是巢狀集模型
詳情可以看我在掘金上的這篇文章,juejin.im/post/5d2288…
大致上來說,它就是一種層級結構的模型。當對層級結構有許多的遍歷操作時,使用它會十分方便。比如獲取某個節點到根節點的路徑,統計節點的子節點數量,或者節點及其子節點所關聯的實體數量(如獲取產品分類樹,及其每個分類節點所擁有的產品數量)。
不過它的缺點是增加、刪除、移動節點會相對而言較為複雜以及消耗效能。 尤其是移動節點,更加複雜。然而在實際應用場景當中,改變某個分類的父分類是一個比較常見的需求。下面我們就來介紹該如何實現這個需求。
如何改變節點的父親節點
我們以如下的分類樹為例子:
如果我們想讓遊戲節點的父節點改成音樂
- 給子樹建立新的空間
UPDATE category SET lft = lft + :width WHERE lft >= :newpos
UPDATE category SET rgt = rgt + :width WHERE rgt >= :newpos
複製程式碼
- 把子樹移動到新空間
UPDATE tags SET lft = lft + :distance,rgt = rgt + :distance
WHERE lft >= :tmppos AND rgt < :tmppos + :width
複製程式碼
- 去除被之前子樹佔據的空間
UPDATE category SET lft = lft - :width WHERE lft > :oldRgt
UPDATE category SET rgt = rgt - :width WHERE rgt > :oldRgt
複製程式碼
各變數說明
int newpos = 4 + 1 // 新的父節點的lft值+1;在這裡音樂節點的lft值是4
int width = node.getRgt() - node.getLft() + 1; // 原子樹的寬度
int distance = newpos - node.getLft(); // 節點到新的位置的距離
int tmppos = node.getLft();
// 向後移動必須考慮新空間
if (distance < 0) {
distance -= width;
tmppos += width;
}
複製程式碼
再經過上面的操作後,整個樹將會變成如下:
總結
除了上面的5次sql操作,其實我們還需要查詢被移動的節點以及新的父節點。所以總的來說至少需要6次sql查詢。一般情況下,修改節點的父節點是一個不太頻繁的操作,所以相對於它帶來的好處,其實是可以接受這樣的效能消耗的。