业务场景:无限级分销如何实时统计团队成员的消费额?

业务场景

用户A可能有N个下级,每个下级也有N个下级,以此类推,如何统计A所有的下级的消费额度?
我的理解只能递归查询或者下级消费时递归更新上级的团队消费额度,不可能实时的查询

今天被一个人问到了,我说:“只能递归查询,要定时更新,无法实时查询”,他说:“我就想要实时查询”,我说:“不知道”。

07-14更新

最近刚知道有图形数据库这个东西,专门处理这种数据,正在学习…

让PHP再次伟大
《L05 电商实战》
从零开发一个电商项目,功能包括电商后台、商品 & SKU 管理、购物车、订单管理、支付宝支付、微信支付、订单退款流程、优惠券等
《L02 从零构建论坛系统》
以构建论坛项目 LaraBBS 为线索,展开对 Laravel 框架的全面学习。应用程序架构思路贴近 Laravel 框架的设计哲学。
讨论数量: 45

这样的项目我做过,我来说一下吧,现在我们需要假设一个前提,就是你的无限级,实际可能会最多有多少级,这个假设要有个度,你不要动不动就说,我有几万级、几十万级,脱离了实际的问题,谈解决没有意义。

说一下以前我做的无限级项目,那项目以前就是采用上面的人说的,每人存了自己上级的所有id,类似1,2,3,4这样存的,查询是使用到了find_in_set来查的,我们一开始,实际数据级数也就10级以下,跑起来还好,后面过了两三年,多的已经有接近100级了,这时候我发现,很多业务,会频繁出现慢查询了,我们那时候也挺烦恼的。

后面我们改了一下,把用户关系,不在使用1,2,3,4这样存储父级关系,我们采用了左右树编码(这里不详细介绍左右树,可以自己百度)来存用户关系,左右树的关系设计,在关系查询的时候,比逗号隔开的时候,是有非常大的区别和提升的,但是这个数据结构,难点不在于查询,而在于移动、删除节点的操作,还好我们项目删除节点也不是特别频繁吧,然后更新的话,有索引,批量更新左右值,也勉强能接受,反正主要是解决查询速度问题就好了。

1年前 评论
勇敢的心 (楼主) 1年前
啊高 1年前
v1i555 1年前
曹孟德 1年前

看你的库表设计了:把根节点存储,每次消费查看当前消费的根节点,实时计算

1年前 评论
小木 (作者) 1年前
勇敢的心 (楼主) 1年前
小木 (作者) 1年前
风中絮 1年前

file
parent_id 是上级, paren_ids 是分销链. 查询用户ID为2的分销链 , 使用 select * from user where find_in_set(2,parent_ids)

1年前 评论
勇敢的心 (楼主) 1年前
keyboby 1年前
勇敢的心 (楼主) 1年前
v1i555 (作者) 1年前
cevin 1年前

国家明文规定直销企业最高只能采用三级分销制,别被逮进去局子喝茶

1年前 评论
勇敢的心 (楼主) 1年前
hon-陈烁临

也不是不可以 ,可以试试下面的思路

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`)
)

把用户上面的所有上级都展开存,如图

file 查A的所有下级

select UserId from teamlevel where ParentId=A

这样存可以查指定的第级,但是实时查数据量大了后还是有很大挑战的。

1年前 评论
勇敢的心 (楼主) 1年前

这样的项目我做过,我来说一下吧,现在我们需要假设一个前提,就是你的无限级,实际可能会最多有多少级,这个假设要有个度,你不要动不动就说,我有几万级、几十万级,脱离了实际的问题,谈解决没有意义。

说一下以前我做的无限级项目,那项目以前就是采用上面的人说的,每人存了自己上级的所有id,类似1,2,3,4这样存的,查询是使用到了find_in_set来查的,我们一开始,实际数据级数也就10级以下,跑起来还好,后面过了两三年,多的已经有接近100级了,这时候我发现,很多业务,会频繁出现慢查询了,我们那时候也挺烦恼的。

后面我们改了一下,把用户关系,不在使用1,2,3,4这样存储父级关系,我们采用了左右树编码(这里不详细介绍左右树,可以自己百度)来存用户关系,左右树的关系设计,在关系查询的时候,比逗号隔开的时候,是有非常大的区别和提升的,但是这个数据结构,难点不在于查询,而在于移动、删除节点的操作,还好我们项目删除节点也不是特别频繁吧,然后更新的话,有索引,批量更新左右值,也勉强能接受,反正主要是解决查询速度问题就好了。

1年前 评论
勇敢的心 (楼主) 1年前
啊高 1年前
v1i555 1年前
曹孟德 1年前

关联查询多对多,下级加入成员,找出当前相关的人员,加入当前分销,查询的时候直接in子查询

1年前 评论

然后我再提一点,回想当年,从我现在的技术眼光来看,近实时的数据统计,其实是有更完美的解决方案的,你可以尝试使用 OLAP 型的数据库,如: clockhouse,买阿里云的话,数据同步的工作你都省了,RDS自动同步过去,这个数据库的效果绝对超乎你想象。

这个方案的前提是老板愿意花钱,愿意给你时间去做,没有这个前提,请你放弃这个方案。

1年前 评论
勇敢的心 (楼主) 1年前
忆往昔弹指间 (作者) 1年前

无限级使用父ID去关联的方式,当层级很深的时候递归效率就很低了,我能想到的就是改表的格式,使用Nested嵌套集合的方式去保存数据,可以避免递归查询,管你多少级。

1年前 评论
lostinfo 1年前

老铁啊,场景都不要想啊,传销违法,开发相关的系统也同样违法,回头是岸。

1年前 评论

上面说的嵌套集合模型是种不错的方式
如果表结构不满足这种方式,可能就要依赖复杂的 SQL 自己来实现这种效果
另外 mysql8 的 with 递归公用表表达式也能实现类似的效果

如果你说的这种表有 100 万以上的数据
建议把统计相关的数据迁移到其他服务, 比如 clickHouse

1年前 评论
勇敢的心 (楼主) 1年前

闭包表,你百度康康。无限级是无解的。。因为你这问题就是N,结果那也是N。

1年前 评论
勇敢的心 (楼主) 1年前

用嵌套级模型带进去能清楚知道当前这个分类是第几层。 相关资料:en.wikipedia.org/wiki/Nested_set_m...

1年前 评论
勇敢的心 (楼主) 1年前

这东西无解的,你10w,100w已经脱离实际了,正常的1000层已经很夸张了,项目没有到达的时候你现在会了到时候还是要踩很多次坑,如果只是想面试有牛可吹那确实没什么.有很多时候,就像并发以前没遇到过,网上教程始终都会和实际业务有些差距,都是实践再根据网上的教程慢慢修改达到业务要求

1年前 评论
勇敢的心 (楼主) 1年前
ononl (作者) 1年前
勇敢的心 (楼主) 1年前

这种把模型简化出来其实就是N叉树,使用N叉树的遍历就可以实现你说的,表就设计成有 pid 把树的数据结构定义好。

1年前 评论
勇敢的心 (楼主) 1年前
white_1998 (作者) 1年前
勇敢的心 (楼主) 1年前

用个字段将所有得上级id全部存储起来,比如pids:1,3,4,5,6,7,在用个pid记录自己得上级 如果想累计团队销售就用find_in_set去查询pids有这个值就ok,这个拆解插入也比较简单 但是数据量大的时候我没尝试过查询时候的速度。

1年前 评论
勇敢的心 (楼主) 1年前

讨论应以学习和精进为目的。请勿发布不友善或者负能量的内容,与人为善,比聪明更重要!