这篇文章是一篇小小的总结,如有疏漏请指出,万分感谢。
分销系统需求
一个分销系统当中,基本有几个要点,我以商品二级分销模型为例子。
1.销售人员发展客户,自己和上级能够获得奖励。
2.当客户购买产品的时候,销售人员和上级也能获得奖励。
3.发展用户或者销售人员时,需要绑定他们的关系。
4.销售人员能够看自己下级的人员并查看自己的销售业绩。
That's all.
不堪回首
当时刚接触这个需求的时候,由于本来用户表有一个 pid(parent_id) 的字段,来表示自己的上级销售人员。我当时竟然可怕的是用了 ppid,pppid来表示更上级的人员。。。。。。我的天,居然有人会做出这种事。多么可怕的一段黑历史。
从文件系统想到分享系统
目前在维护一个有上千亿行数据的文件系统,分表分8192张。表结构里面有一个字段,专门维护文件夹层级,里面的值遵循一定的数据格式,长得很像linux的文件系统层级结构(例如:/usr/bin/local/),可以说是一模一样。突然,这不就是树结构吗?然后想到了分销系统的树结构
开干!
用户表字段设计:user_id,parent_id,tree,level,money
这里涉及到一些家喻户晓的人,分别是,A,B和Cn
他们有相关从属的关系。
用表来表示:
A进了某养生品公司,注册了会员。
于是A成为了这个系统的第一个用户
| user_id| parent_id | tree| level| money|
| ------------- |:-------------:| -----:|
|A|没有爸爸|/|1|0|
这时A走在大街上,看到B,说:“你听说过安利吗? blablabla”
然后B扫码成为了A的下级会员,A获得一块钱的发展会员奖励,并告诉他,你可以告诉你的新朋好友哦,卖出这么好的产品,可以分成哦。
于是有了
| user_id| parent_id | tree| level| money|
| ------------- |:-------------:| -----:|
|A|没有爸爸|/|1|1|
|B|A|/A/|2|0|
那么B开始努力推广安利这个产品
给认识的熟人(C1,C2,C3)安利了一发
于是有了
| user_id| parent_id | tree| level| money|
| ------------- |:-------------:| -----:|
|A|没有爸爸|/|1|4(1+3)|
|B|A|/A/|2|3(0+3)|
|C1|B|/A/B/|3|0|
|C2|B|/A/B/|3|0|
|C3|B|/A/B/|3|0|
很明显了
这个表设计的优点
1.可以通过 tree 很快的找到 C1 用户的所有上级用户进行相关操作
2.可以通过 like tree 操作,利用索引,查询 A 用户所有的下级进行相关计数操作,可以提高 A 的推广积极性
3.通过用 tree 属性去关联订单表,给上级返利或者查询自己的推广所得,也是很方便。
tree 与 linux 文件系统忒像了
其实这个分销的树形结构像极了文件系统的标识符,我也是在做相关mysql存储文件关系的业务当中类比出如此高效快速的查询方法。
缺点
这个设计模式的缺点也很明显,一旦关系转移(类似文件夹移动),就会产生大量的tree字段修改。所幸的是:关系转移可以异步处理,但查询关系就必须同步。鉴于这种操作特点,也就可以采取这种模式。