網站應用系統設計分享-改進的前序遍歷樹模型

設計初衷:由於網站應用系統間存在欄目之間的上下級關係,需要採用樹結構進行存儲。通常我們設計的樹結構的數據庫設計爲:
c_id, c_parent_id, c_name, ... 這樣的。但是在網站應用系統的業務中,有非常多的查看樹以及其下所有節點的信息的功能。
比如:查看審判動態欄目以及欄目下所有子欄目的文章,對應到法院業務比較常見的應該是法院及其下轄院(但是這種情況被法院國標碼完美解決)。
那麼,按照原有設計應該如何實現呢?就可能需要遞歸的方式獲取到樹上所有的節點,然後根據這些節點進行查詢。
但是,這種方式會隨着樹的深度的增加,增加遞歸的深度。當然,也可以用緩存將整個樹都存起來,進行遍歷。但是這樣真的是最好的麼?

於是引入改進的前序遍歷樹模型(The Nested Set Model)來解決問題。

那麼,什麼是改進的前序遍歷樹模型呢?

原理
首先把樹按照水平方式擺開。從根節點開始(“Food”),然後在左邊寫上1。然後按照樹的順序(從上到下)給“Fruit”的左邊寫上2。這樣,沿着樹的邊界遍歷,然後同時在每個節點的左邊和右邊寫上數字。最後,我們回到了根節點“Food”在右邊寫上18。下面是標上了數字的樹,同時把遍歷的順序用箭頭標出來了。

1491013952785_2.jpeg (40.17 KB, 下載次數: 0)

下載附件  保存到相冊

model

2017-4-1 15:10 上傳




數據庫
parent
title
lft
rgt
 Food
1
18
Food
Fruit
2
11
Fruit
Red
3
6
Red
Cherry
4
5
Fruit
Yellow
7
10
Yellow
Banana
8
9
Food
Meat
12
17
Meat
Beef
13
14
Meat
Pork
15
16
這樣,通過lft和rgt字段,就能明確的查詢出想要的結果了。

附上一些在實際中正在使用的SQL:

返回完整的樹
  • SELECT node.name
  •   FROM nested_category node, nested_category parent
  • WHERE node.lft BETWEEN parent.lft AND parent.rgt
  •   AND parent.name = 'electronics'
  • ORDER BY node.lft



返回所有葉子節點
  • SELECT name FROM nested_category WHERE rgt = lft + 1;



插入節點
  • LOCK TABLE nested_category WRITE;
  • SELECT @myRight := lft FROM nested_category WHERE name = 'TELEVISIONS';
  • UPDATE nested_category SET rgt = rgt + 2 WHERE rgt > @myRight;
  • UPDATE nested_category SET lft = lft + 2 WHERE lft > @myRight;
  • INSERT INTO nested_category
  •   (name, lft, rgt)
  • VALUES
  •   ('GAME CONSOLES', @myRight + 1, @myRight + 2);
  • UNLOCK TABLES;


刪除節點
  • LOCK TABLE nested_category WRITE;
  • SELECT @myLeft := lft, @myRight := rgt, @myWidth := rgt - lft + 1
  •   FROM nested_category
  • WHERE name = 'GAME CONSOLES';
  • DELETE FROM nested_category WHERE lft BETWEEN @myLeft AND @myRight;
  • UPDATE nested_category SET rgt = rgt - @myWidth WHERE rgt > @myRight;
  • UPDATE nested_category SET lft = lft - @myWidth WHERE lft > @myRight;
  • UNLOCK TABLES;




以上就是改進的前序遍歷樹模型的常用sql。


目前網站應用系統正在使用這個模型解決業務上的問題,如果你覺得還不錯,也可以考慮使用一下哦~
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章