一个多层级节点用户树的设计构思
生活随笔
收集整理的這篇文章主要介紹了
一个多层级节点用户树的设计构思
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
背景:
由于近期一個項目要開發一個多層級用戶體系,并且還要支持部分鏈條的可移動性,經過初步構思,已經有了一個初步的思路,今天在這里簡單分享一下。
要求:
1. 用戶結點數要支持百萬級,層級理論上支持無限級擴展 2. 支持節點動態插入(不支持刪除,通常也不會有這種需求,需要的話采用節點狀態來處理) 3. 支持葉子節點可移動(中間節點不可以移動) 4. 支持一級節點可替換(也就是說可以把某個一級節點下面的所有節點遷移到另外一個一級節點下面)
實現方式:
1. 采用mysql單表設計 2. 采用redis實現分布式鎖 ?(本篇暫不討論實現)
表設計:
說明: id: 主鍵,自增 bid: ?節點業務id(獨立唯一索引,bid不允許重復) layer: 節點所處層級,一級節點為1,二級節點為2,依此類推 parent_bid: 當前節點的上級節點業務 id top_bid: 當前節點所屬一級節點的 bid (獨立索引)
初始數據:
初始結構:
操作:
1. 新增節點
? ? 1) 新增一級節點
? ? ? ? ?layer = 1, parent_bid = 0 , top_bid = 0, 通過 top_bid = 0 可以查詢出所有一級節點,別忘了 top_bid 有獨立索引。? ? 2) 新增非一級節點?
? ? ? ? 首先找到上級節點(parent),然后 cur(layer) = parent(layer)+1; ?cur(parent_bid) = parent(bid); ?
cur(top_bid) = ?parent為一級節點? ?parent(bid) : parent(top_bid)2. 移動節點
1) 移動葉子節點
? ? ? ?cur(layer) = target(layer)+1; ?cur(parent_bid) = target(bid); ?cur(top_bid) = target為一級節點?target(bid) : target(top_bid)2) 替換一級節點
? ? ? ?比如,把 bid_1 下面整個子鏈條遷移到 bid_5的下面,用target表示 bid_5節點。? ? ? ?2.1) bid_1 的直接下級要修改 parent_bid = target(bid)
2.2) ?bid_1整個子鏈條節點的新的top_bid: ? new_top_bid = target為一級節點? ?target(bid) : target(top_bid), ? ? ? ?用sql表示為 update tree set top_bid =?new_top_bid?where top_bid = "bid_1"
?3. 查詢
? ? ? ?如果要查詢節點的話,目前只能是一級一級的查看,不支持查看一個節點的整個下級網絡安全修改
? ? ? ?在新增和移動節點的過程當中,如果有并發操作的話,容易把數據弄亂,而且不可恢復,那 將是災難性的后果。考慮到跨多個jvm,單純的java鎖是解決不了問題的,所以這里必須使用 分布式鎖。
1) 可以使用分布式讀寫鎖,由于多個新增操作不會有沖突,所以新增操作可以使用讀鎖; 所有的移動操作都是互斥的,所以可以使用寫鎖; 分布式讀寫鎖自己實現的話會比較麻煩, 如果系統并發量不是很大,可以考慮使用2)中的方式。 2) 使用普通的分布式鎖,相當于實現一個跨jvm的同步操作,可以使用redis簡單實現一個 分布式鎖,以后有時間再單獨寫一篇來介紹如何實現。
安全日志:
? ? ? ?如果你的實現有bug,比如移動節點代碼寫的有問題,導致整個層級結構錯亂了,該怎么辦? 可以創建一張 log表,按時間順序 ,記錄下每一個新增操作和移動操作,修改用戶名、手機之類 的不需要記錄,如果層級出現錯誤了,以后還可以寫個腳本執行log中的所有操作命令,還是 有機會重建出整個層級樹出來的。
其它:
? ? ? ?需求的變化是無止境的,一個模型適應不了所有的需求,有時候,是需要商務去引導客戶的。 基于以上模型也是有缺陷的,比如,不可以隨便移動任意節點,不能簡單就可以查看一個用戶 所有下級網絡等。 但也是有替代方案的,比如,查詢下級用戶的話,一層一層來查詢; 任意移 動節點的話,由于操作肯定很少,真有需求,可以考慮找出所有相關節點,一個一個update,放 在一個事務中。
后話:
? ? ? ?多層級的設計是非常靈活多變的,要看場景和需求,以及多大的擴展能力和數據大小,沒有最好,只有最適合。
總結
以上是生活随笔為你收集整理的一个多层级节点用户树的设计构思的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: web端接入微信小程序扫码进行登录
- 下一篇: 什么是IP地址冲突?如何解决IP地址冲突