首先說明一下,這個方案比較難理解,以前做過類似系統(沒做過傳銷,是保險行業的類似需求),跳過不少的坑,回頭看來,這個方案算是比較靠譜的Mysql數據庫實現。如果哪位朋友有其他更好的辦法,歡迎留言交流。
用“傳銷”二字,是為了好理解,大家能形象化的入題,僅此而已!
當時沒有考慮過Neo4J等圖形數據庫的實現方案,Redis等NoSQL組件倒是考慮過,但是都覺得不妥,最終還是堅持了這套Mysql方案。
基本業務:
用戶A介紹B入會,B成為A的下線,B再發展C、D等下線,C、D也允許再發展下線,不限制層級,但是每個人只允許有一個上線。典型樹結構。
要解決的幾個功能點需求(增刪改查):
要求快速查詢某人K的所有下線
要求查詢某人L的所有上線
要求快速刪除某人P及其所有下線
要求快速的為某人X增加一個下線
看似簡單,實際有無數的坑,我直接上方案。
數據庫設計:
看不懂不要緊,left 和 right 字段請繼續看下面樹圖中的紅字:
數據表示的樹形結構:
上面數據表的 left 和 right 明白什麼意思了吧,就是前序遍歷,每次+1
上面對實現方案先進行了劇透,現在來說明該方案怎樣滿足我開篇提到的幾個需求:
要求能夠快速查詢某人K的所有下線
select id from A where left < #K_left and right > #K_right
要求快速查詢某人L的所有上線
select id from A where left < #L_left and right > #L_right order by left ASC
要求能夠快速刪除某人P及其所有下線
delete from A where left >= #P_left and right <= #P_right
update A set left = left – (#P_right - #P_left + 1) where left > #P_left
update A set right = right – (#P_right - #P_left + 1) where right > #P_right
三步:1、刪除;2、更新所有引起變動節點的left;3更新所有引起變動節點的right
要求快速為某人X增加一個下線
update A set right = right + 2 where right >= #X_right
update A set left = left + 2 where left >= #X_right
insert into A(name, left, right)values('馬雲', #X_right, #X_right + 1)
三步:1、更新引起變動節點的right;2、更新引起變動節點的left;3、插入數據
上面的刪除和增加合起來就是整體挪動某人成為另一個人的下線。
另外,如果要挪動某人和他的下線整體到另一個人下面,方案基本一樣,不過計算left和right的時候多考慮一點,留作練習題吧,開動下腦筋,哈哈。
提醒,SQL難理解的話,咱們就自己畫個圖,動手數一下,一目瞭然!
喜歡本文的朋友歡迎 “關注” !謝謝。