首先说明一下,这个方案比较难理解,以前做过类似系统(没做过传销,是保险行业的类似需求),跳过不少的坑,回头看来,这个方案算是比较靠谱的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难理解的话,咱们就自己画个图,动手数一下,一目了然!