一种避免递归查询的树状数据表设计与实现 - 科技金融 -

当前位置:首页  >  科技金融  > 正文

一种避免递归查询的树状数据表设计与实现

一种避免递归查询的树状数据表设计与实现
2023-03-16 07:20:13 来源:腾讯云

通常树形结构的存储,是在子节点上存储父节点的编号来确定各节点的父子关系,例如这样的组织结构:

与之对应的表数据(department):

部门表结构(department)


(资料图片)

id部门编号name部门名称level所在树层级parent_id上级部门编号

问题来了

这样的方式很不错,可以很直观的体现各个节点之间的关系,通常可以满足大多数需求。但是当业务需求变得多了,数据量庞大了,这样的方式就不再适合用于生产。

例如:PM加了以下需求:

查出指定部门下所有子孙部门查询子孙部门总数判断节点是否叶子节点

查出所有子孙部门

使用指定部门编号,一层一层使用递归往下查,可能是多数人会想到的方法。尽管在mysql8.0支持了 cte(公共表表达式),递归效率比传统递归方式有明显提升,但是查询效率仍会随着部门树层级深度的提高而变差。

另外一种方法,一次性查出所有数据,放入内存中处理(数据量少时,可以选用。数据量多,不怕挨打的人也可以选这种)~

查询子孙部门总数

递归查询每一层的数量,最后相加。

判断是否叶子节点

方法1:可以加字段isLeaf的方式,来表示这个节点是否是叶子节点。

方法2:直接通过查询parent_id=当前id的count是否大于0,大于0表示不是叶子节点,等于0表示为叶子节点。

在日常中,可能会经常使用上述类似方法去解决类似的问题,但我觉得这样的方法在效率上不是最优解。于是乎开始查找更好的方案去解决这些问题。

| 要不试试这个方法?

直到后面查到国外一博客中,见到了所谓的《改进后的先序树遍历》文章(天哪,竟然是一篇2003年发表的文章)~

他具体是怎么做的呢?

还是回到刚刚的组织架构

我们从根节点开始,给董事长左值设为1,下级部门总经理左值设为2,以此类推地沿着边缘开始遍历,给每个节点加上左值,遇到叶子节点处给节点加上右值,再继续向上沿着边缘继续遍历,遍历结束回到根节点右侧,你将得到类似这样的结构。

遍历完后每一个节点都有与之对应的左右值。这个时候可以去除parent_id字段,添加lft,rgt,来存储左右值。

数据和结构准备完毕,我们来试试操作解决上面的需求~

查出所有子孙部门

根据当前表结构的规律,可以发现,要想查出所有子孙部门,只要查左值在 被查寻部门的左\右数之间的节点,查出来都是他的子节点。例如:查询行政总监的所有子部门,行政总监的左右数是9和18,因此只需要用9和18做lft字段的between查询,查询出的结果就是【被查部门本身数据和所有子孙部门】;

SET@lft:=9;SET@rgt:=18;SELECT*FROMdepartmentWHERElftBETWEEN@lftAND@rgtORDERBYlftASC;/*例子中用BETWEEN将被查部门本身也查了出来。实际中可以用大于小于*/完美~

查询子孙部门总数

到这里可能会说,需求1都解决了,查总数自然也就解决了,直接上select count就可以了,确实没有错,但是没有那个必要,因为有个简单公式可以直接计算。

公式:总数 = (右值 - 左值 - 1) / 2

例如:

行政总监的子孙部门数=(18-9-1)/2=4董事长的子孙部门数=(20-1-1)/2=9会计的子部门数=(14-13-1)/2=0可以数数看,确实没错哦~

判断是否叶子节点

通过有了上述计算公式算总数的经验后,现在判断是否叶子节点,有的小伙伴已经知道了怎么做,那就是:

右值 - 1 == 左值那他就是叶子节点,或者左值 + 1 == 右值那他就是叶子节点,反之则不是叶子节点。

例如:

设计部,5 - 1 == 4,因此他是叶子节点。

董事长,20 - 1 != 1,因此他不是叶子节点。

至此已经完美的解决了上述需求问题,接下来再尝试一下业务的基本操作。

其他基本操作

新增部门

当新增一个部门时,需要对新增节点位置的后续边缘进行加2操作,因为每一个节点有左右两个数值。这个操作通常需要放到事务中进行处理。例如:在研发部门下添加一个新部门:

对应sql:

SET@lft:=7;/*新部门的左值*/SET@rgt:=8;/*新部门的左值*/SET@level:=5;/*新部门的层级*/begin;/*将插入的后续边缘的节点左右数+2*/UPDATEdepartmentSETlft=lft+2WHERElft>@lft;UPDATEdepartmentSETrgt=rgt+2WHERErgt>=@lft;/*插入数据*/INSERTINTOdepartment(name,lft,rgt,level)VALUES("新部门",@lft,@rgt,level);/*新增影响行数为0时,必须回滚*/commit;/*rollback;*/

删除部门

删除部门与新增部门类似,不同的是需要对删除节点的后续边缘节点减2操作。例如:删除刚刚添加的新部门:

对应sql

SET@lft:=7;/*要删除的节点左值*/SET@rgt:=8;/*要删除的节点右值*/begin;UPDATEdepartmentSETlft=lft-2WHERElft>@lft;UPDATEdepartmentSETrgt=rgt-2WHERErgt>@lft;/*删除节点*/DELETEFROMdepartmentWHERElft=@lftANDrgt=@rgt;/*删除影响行数为0时,必须回滚*/commit;/*rollback*/

查询直接子部门

查询某部门的直接子部门(即不包含孙子部门),例如:查询总经理下的直接子部门。正常需要返回产品部和行政总监

对应的sql

SET@level:=2;/*总经理的level*/SET@lft:=2;/*总经理的左值*/SET@rgt:=19;/*总经理的右值*/SELECT*FROMdepartmentWHERElft>@lftANDrgt<@rgtANDlevel=@level+1;

查询祖链路径

查询某部门的祖链路径。例如:查询产品部的祖链路径,正常需要返回董事长,总经理

SET@lft:=3;/*产品部左值*/SET@rgt:=8;/*产品部右值*/SELECT*FROMdepartmentWHERElft<@lftANDrgt>@rgtORDERBYlftASC;

树形数据展示(JS示例)

letlist=[//模拟sql查出来的列表。{id:1,name:"root",lft:1,rgt:8,level:1},{id:2,name:"child",lft:2,rgt:7,level:2},{id:3,name:"grandson",lft:3,rgt:4,level:3},{id:4,name:"grandson2",lft:5,rgt:6,level:3}];letrights=[]/*类似于一个栈结构(后进先出)*/letmp={}//list.sort((a,b)=> a.lft - b.lft)//如果你在sql中没有进行排序,需要在这里给他排序。list.forEach(item=>{if(rights.length>0){while(rights[rights.length-1]{let_tree=[];_list.forEach(item=>{if(item.parent_id==parent_id){letchilds=recursive(_list,item.id)_tree.push({...item,children:childs.length>0?childs:(item.isLeaf?null:[])})}})return_tree}console.log(recursive(list))

完结

在我目前看来,这个方法的唯一缺点就是,每一次的新增或删除,操作节点的后续边缘走到的节点都要加/减2操作。

标签:

(责任编辑:news01)
库里空砍40+6+7吉迪大三双 勇士不敌雷霆遭两连败

库里空砍40+6+7吉迪大三双 勇士不敌雷霆遭两连败

央视网消息:北京时间3月8日,NBA常规赛,雷霆主场137-128力克勇士,迎来三连胜的同时送给对手两连败。...
03-08 14:56:26
韩愈的资料 世界今热点

韩愈的资料 世界今热点

1、韩愈(768年-824年12月25日),字退之,河南河阳(今河南省孟州市)人。2、自称“郡望昌黎”,世称...
03-08 14:17:27
老年网认证_老年网_世界热资讯

老年网认证_老年网_世界热资讯

1、老年网认证的操作办法是先下载社保。2、然后按手机上指示的去做,让你输身份证号,你就输入身份证的...
03-08 12:21:16
高铁学生票打折吗 全球热点

高铁学生票打折吗 全球热点

高铁学生票打折,不过只能用学生证购买二等座,其余坐席不发售学生票,使用学生证购买二等座车票可以享...
03-08 11:14:21
全球资讯:so basically老友记(so basic)

全球资讯:so basically老友记(so basic)

1、sobasic,是衣恋集团又一主力品牌,相对价格有优势,并具有很强烈的卖点(服饰上沿袭了TW风格),上...
03-08 10:01:34
振东制药:融资净偿还607.18万元,融资余额3.18亿元(03-07)

振东制药:融资净偿还607.18万元,融资余额3.18亿元(03-07)

2023年3月7日振东制药融资净偿还607 18万元,融资余额3 18亿元
03-08 08:31:27
武警制服 当前关注

武警制服 当前关注

1、武警警服为橄榄绿色的制式服装,分为军官礼服、两团一队礼服、常服系列作训服系列,常服系列包括春秋...
03-08 07:48:10
过了个暖冬,该准备T恤了!学会这几种穿搭,让你瞬间高级又时髦 今日看点

过了个暖冬,该准备T恤了!学会这几种穿搭,让你瞬间高级又时髦 今日看点

准备好吧,是谁说的今年是个暖冬?请靠前一步站出来。我此刻已经甩掉秋裤写文章了。这天实在太热,让我...
03-08 05:02:52
pcmark_当前头条

pcmark_当前头条

1、PCMark检测系统整体性能PCMark主要用于检测系统整体性能,并通过软件给出的综合评价分值评估系统的性能。2、
03-08 04:07:07
奇洛教授简笔画_奇洛教授

奇洛教授简笔画_奇洛教授

今天小编岚岚来为大家解答以上的问题。奇洛教授简笔画,奇洛教授相信很多小伙伴还不知道,现在让我们一起...
03-08 00:07:21
山西中阳县

山西中阳县

1、中阳县。2、隶属于山西省吕梁市。3、位于山西省西部。文章到此就分享结束,希望对大家有所帮助。
03-07 20:44:30
excel怎么输入平方2_怎么在excel表中输入平方|世界新消息

excel怎么输入平方2_怎么在excel表中输入平方|世界新消息

1、  Excel中也经常会用到一些数据的`平方。那么怎么在excel表中输入平方呢?下面就让小编来告诉大家怎么在exc
03-07 20:43:17
黑龙江省桦南县发布暴雪黄色预警

黑龙江省桦南县发布暴雪黄色预警

黑龙江省桦南县发布暴雪黄色预警
03-07 18:08:16
天下谁人不识君的上一句-当前热闻

天下谁人不识君的上一句-当前热闻

1、天下谁人不识君的上一句是莫愁前路无知己。2、原文:千里黄云白日曛,北风吹雁雪纷纷。莫愁前路无知...
03-07 17:37:22
联迪信息(839790)3月7日主力资金净卖出28.66万元_天天快资讯

联迪信息(839790)3月7日主力资金净卖出28.66万元_天天快资讯

截至2023年3月7日收盘,联迪信息(839790)报收于5 83元,下跌1 85%,换手率1 59%,成交量3576 92手,成交额209 34万元。
03-07 16:22:41
一晃一年过去朋友圈的说说

一晃一年过去朋友圈的说说

1、一转眼又快到年底了,不知道这一年都忙了些什么!反正时间就这么匆匆过去了。一年看似很长实则一闪而...
03-07 14:37:44
场馆周边“旧貌换新颜”了吗?-全球热资讯

场馆周边“旧貌换新颜”了吗?-全球热资讯

亚运会迎来倒计时200天场馆周边“旧貌换新颜”了吗?瓯海亚运公园的建设积极融入各种亚运元素。园林工人...
03-07 14:09:54
盛大传奇官网网站是多少_盛大传奇官网1 76 全球热推荐

盛大传奇官网网站是多少_盛大传奇官网1 76 全球热推荐

1、现在传奇版本超多想找到一款适合自己的很不容易找一款好玩的也不是很容易。2、有些版本注定了,这个...
03-07 12:00:45
全球新消息丨索尼爱立信k800

全球新消息丨索尼爱立信k800

1、索尼爱立信K800,是一款以拍照功能为主打的手机,采用2 0英寸的26万色QVGA屏幕,屏幕表现相当出色。2、在功能
03-07 11:15:18
赣州经开区:税惠“春风”为涉农企业送暖-全球报资讯

赣州经开区:税惠“春风”为涉农企业送暖-全球报资讯

中国青年网赣州3月6日电向阳草木青,明媚春光暖。在赣州经开区,春节后开工的涉农企业呈现出一片热火朝...
03-07 10:04:30
香精香料英才网-微资讯

香精香料英才网-微资讯

1、 "[] "。文章到此就分享结束,希望对大家有所帮助。
03-07 08:25:45
每日播报!设计英文翻译怎么写_设计英文翻译

每日播报!设计英文翻译怎么写_设计英文翻译

1、有高手翻译英文吗?我眼中的室内设计作为一名学环境艺术设计专业的学生。2、我Theinteriordesign
03-07 07:58:35
休闲鞋搭配_休闲鞋搭配 精选

休闲鞋搭配_休闲鞋搭配 精选

2 运动休闲鞋色彩搭配丰富。如果搭配的衣服颜色单调,可以选择色彩比较活跃的运动休闲来搭配,变得明亮...
03-07 04:35:00
1元硬币哪年最值钱_1元硬币

1元硬币哪年最值钱_1元硬币

1、1980年4月15日起发行1元硬币为铜镍合金,银灰色;1991年-2000年间发行的牡丹图案1元硬币,钢芯镀镍材质;
03-07 03:02:00
最新消息!伊藤美诚豪言:如果世锦赛女团夺冠,我折寿都无所谓!

最新消息!伊藤美诚豪言:如果世锦赛女团夺冠,我折寿都无所谓!

日本选手都很年轻,18岁,19岁的很多,下一年龄段日本的乒乓球一定会压过中国,就咱们这样薄弱的乒乓球...
03-06 22:58:57
2021三月三的文案怎么写 关于三月三的优美文案短句

2021三月三的文案怎么写 关于三月三的优美文案短句

2021三月三的文案怎么写关于三月三的优美文案短句1、三月三,祝你元气满满,幸福满满,生活一切都美满!...
03-06 21:11:48
视频调色软件DaVinci Resolve 18.1.4发布 环球实时

视频调色软件DaVinci Resolve 18.1.4发布 环球实时

IT之家3月6日消息,BlackmagicDesign今天发布了DaVinciResolve18 1
03-06 20:03:04
妻子出轨了婚姻还能继续吗_妻子出轨了 滚动

妻子出轨了婚姻还能继续吗_妻子出轨了 滚动

1、当老婆出轨,老婆有外遇,被老婆戴绿帽子,很多男人都不愿意直视这件事,选择逃避。我能理解咨询师此...
03-06 17:58:23
小火车托马斯全集 全球观热点

小火车托马斯全集 全球观热点

1、《托马斯与小火车们》是一款儿童类网页游戏。本文到此结束,希望对大家有所帮助。
03-06 17:56:26
酬乐天扬州初逢席上见赠刘禹锡

酬乐天扬州初逢席上见赠刘禹锡

酬乐天扬州初逢席上见赠百科名片  《酬乐天扬州初逢席上见赠》是唐代刘禹锡的七言律诗。唐敬宗宝历二...
03-06 16:01:04

为您推荐

精彩推送