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