战狂粗人张

  博客园 :: 首页 :: 博问 :: 闪存 :: 新随笔 :: 联系 :: 订阅 订阅 :: 管理 ::

一、背景

1、在现实生活中我们经常遇到由推荐人注册,比如一个购物平台,用户A推荐用户B注册,那当B购买商品成功时,用户A就会拿到相应的提成。

只要是用户A推荐的用户购买商品成功后,A用户都会拿到提成。

当用户B推荐了用户C,那当用户C购买商品成功时,用户B和用户A都可以拿到相对应的提成。

如果用户C推荐了用户D,那当用户C购买商品成功时,用户C,用户B和用户A都可以拿到相对应的提成。

以此类推。这就是我们所说的分销。

 

2、什么是二级分销?

二级分销其实是一种让用户分裂通过邀请的形式来获得更多的用户。如有ABC三个人,A推荐B购买一件商品,B推荐C购买一件商品。

假定通过直接推荐购买该商品可获得10%利润,通过间接推荐购买可获得5%的利润。

设这件商品定价为1000元,结算下来A可以获得100+50=150元的利润,B可以获得100元的利润,这就是二级分销。

 

二、需求

常见的功能如下:

1、等级

所有参与者都可以成为代理商,即系统满足无限级分销;

分销商只能获取三级分销所得的佣金,超过三级的部分不能获得佣金。

2、权限

上级代理可以查看下级代理,以及下级代理的所有下级代理的订单;

下级代理不能查看上级代理的订单;

同级不能查看对方以及他的下线订单。

3、返佣

A->B->C->D->E->F->客户小明。

如上分销体系中,客户小明从分销商F那里购买了商品,那么F获得一级佣金,E获得二级佣金,D获得三级佣金,D前面的分销商C,B,A就与此没有关系,也无法获得佣金。

一级佣金比例是5%,二级是3%,三级的是2%

4、题外话

分销一般分为三级,分销商超过三级是犯法的。

2010年5月7日,《最高人民检察院、公安部关于公安机关管辖的刑事案件立案追诉标准的规定(二)》发布,

其在第七十八条中规定 “涉嫌组织、领导的传销活动人员在三十人以上且层级在三级以上的,对组织者、领导者,应予立案追诉”。


三、方案

1、首先是用户注册信息表UserInfo需要增加一个ParentId字段。

根据上图,userid=1的这个会员Pid为0的说明会员是顶级的,没有任何人推广。

userid=2的这个会员pid为1,说明他是userid为1的会员推广而来。然后看userid=7的这个会员,他的pid=2,说明他是userid=2的这个会员推广来。说白了推广关系就是:

userid(1)->userid(2)->userid(7)

userid(1)->userid(3)

userid(1)->userid(4)

userid(1)->userid(5)

userid(1)->userid(6)

那么我们要查询一个会员(假设他的id为1)所有的推广一级会员,对应的sql就是:select * from t_user where Pid=1,这里没有什么问题,到是不难。

那继续来,要查询他的二级或是三级分销会员的话,就麻烦了,需要使用子循环了。对应的代码如下:

public String gets(int pid){
  StringBuffer sb=new StringBuffer(sb);
  ArrayList list=(ArrayList)DaoFactory.getUserDAO().exe("select id,Pid from t_user where Pid="+pid);
  for (Iterator iter = list.iterator(); iter.hasNext(); ) {
        DataField df=(DataField)iter.next();
  sb.append("<li>"+df.getInt("id")+"</li>");
  //递归调用
  sb.append(gets(df.getInt("id")));
  }
}

上面看到了,主要解决办法就是递归调用。

虽然功能也能实现,但在数量比较大的情况下,很容易产生性能问题(这里只是查找会员,如果在统计每个级别下会员的消费,收入统计时,需要和消费表关系查询,那性能不知卡到什么时候)。

下面重点来了,我们重新设计一下表,这里我们主要是通过数据库设计来解决,

我们知道数据库存储数量量不怕多,于是可以这样,每当用户推广一个会员的时候,我们向一个表(暂且叫作用户关系表)写入他的级别关系不就行了吗。

比如 a推广了b,然后b推广了c,c推广了d,这样我我们就向数据库中写一个记录b以上三级的关系。

然后,新建一张层级关系表TeamLevel,表结构如下:

CREATE TABLE `teamlevel` (
  `Id` bigint(20) NOT NULL,
  `UserId` varchar(50) DEFAULT NULL COMMENT '用户Id',
  `ParentId` varchar(50) DEFAULT NULL COMMENT '推荐人Id',
  `Level` int(10) DEFAULT NULL COMMENT '层级',
  PRIMARY KEY (`Id`)
)

比如:

例子:

在做交易所的时候,需要统计邀请注册人数,比如 A邀请B, B邀请C, C邀请D。那么A的邀请人数就是3个,B的邀请人数就是2个,C的邀请人数就是1个。

除此之外,还要能统计出A直接邀请人数,A下一级邀请人数,A下二级邀请的人数,以此类推。

 

2、在注册的时候需要往这张表插入数据,比如D推荐E来注册,就需要往库里插入如下记录:

 

有了这些记录之后,查询统计就方便多了,用户的层级关系也一目了然。

 

再比如:

这里看到,ChildId=2的这个会员,他是id为1(Pid=1)的一级分销用户(FxLevel=1)

ChildId=7的这个会员,数据库中有两条记录,一个是:他是id为2(Pid=2)的一级分销用户(FxLevel=1),

再就是他是id为1(Pid=1)的二级分销用户(FxLevel=2),所以不难理解,如果一个会员上面有三级的话,这里应该有三条记录。

简单理解就是,当用户新增加时,将此用户上面所有级别对应的用户信息记录到用户关系表中。

这样,当我们要查询一个会员所有一级会员时,

可以使用sql:select * from t_user_relations where Pid=1 and FxLevel=1

所有二级会员sql:select * from t_user_relations where Pid=1 and FxLevel=2

所有三级会员sql:select * from t_user_relations where Pid=1 and FxLevel=3

当我们需要统计三级会员的消费总额的时候,

可以很方便使用sql:select sum(t_pay.Money) from t_user_relations,t_pay where t_user_relations.ChildId=t_pay.Userid and t_user_relations.Pid=1 and t_user_relations.FxLevel=3

同理查询二级会员的消费:select sum(t_pay.Money) from t_user_relations,t_pay where t_user_relations.ChildId=t_pay.Userid and t_user_relations.Pid=1 and t_user_relations.FxLevel=2

那要查询所有子会员的消费怎么办?总不能写三个sql吧,当然不会了。使用条件FxLevel>0不就可以了吗:)

select sum(t_pay.Money) from t_user_relations,t_pay where t_user_relations.ChildId=t_pay.Userid and t_user_relations.Pid=1 and t_user_relations.FxLevel>0

这样一个sql就解决了。如果使用一开始使用的递归方法,随着数据量的增长,速度会非常非常的糟糕。

上面你还可能 还会问一个问题,那如果知道某个会员他是谁的一级,谁的二级呢,.....?这需要用到第一个方法设计的表了,看到了,上面的表设计我们还是要用到:)

select Pid from t_user where id=2

if(Pid!=0)说明还不是顶级,继续查。这里可以 使用递归查询或做三次查询(通过 pid是否为0,这样有的可能只是一级或两次查询,最多就是3次),放心,这样的不会太影响性能的,可以忽略不计。

或者把id,pid数据放到缓存里,redis是个不错的选择。

 

posted on 2021-01-29 15:54  战狂粗人张  阅读(249)  评论(0编辑  收藏  举报