首页 >热点 > > 正文

全球快播:一种避免递归查询的树状数据表设计与实现

腾讯云 2023-03-18 07:20:57

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

与之对应的表数据(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操作。

上一篇:全球微头条丨周星驰朱茵为什么分手老梁_周星驰朱茵为什么分手 下一篇:最后一页
x
推荐阅读

全球快播:一种避免递归查询的树状数据表设计与实现

2023-03-18

全球微头条丨周星驰朱茵为什么分手老梁_周星驰朱茵为什么分手

2023-03-18

新宋txt全集下载完整版_新宋txt全集下载

2023-03-17

全球速讯:吃米饭和面食哪一个更容易发胖_吃米饭和面食哪个好

2023-03-17

世界滚动:“住学产行康”一体化推进!桃浦智创城国际化生态示范区形态初显

2023-03-17

微资讯!美国两日内发生第四起火车脱轨事故:21节车厢倾覆 部分车厢裂开

2023-03-17

全球速看:孟子生平简介资料_孟子生平简介

2023-03-17

山东黄河生态景观建设

2023-03-17

早盘:海外机构近期调研股出炉(附股)_世界新要闻

2023-03-17

食品价格大涨 瑞典通胀水平高企 全球快讯

2023-03-17

平板ipad6是什么型号_ipad6是什么型号

2023-03-17

播报:欧洲银行业担忧上升 市场加息预期下滑;

2023-03-16

贝壳W:2022年年净亏损13.97亿元

2023-03-16

乌鲁木齐周大福今日金价查询(2023年3月16日)

2023-03-16

今天最新消息 海南新增本土确诊病例426例 本土无症状感染者785例-天天头条

2023-03-16

信澳量化多因子混合(LOF)A基金经理发生变更 全球快消息

2023-03-16

警惕“消费刺客”陷阱

2023-03-16

即时看!尾随女子入室奸杀纵火 恶魔19年后落网

2023-03-16

新动态:正阳县气象局发布大风蓝色预警【IV级/一般】【2023-03-16】

2023-03-16

天天最新:联通混改板块3月15日涨0.03%,ST易购领涨,主力资金净流出5.52亿元

2023-03-16

环球观焦点:上游315 | 售价8.8元销量10万+的电动车头盔你敢买?有博主一锤打瘪“便宜货”

2023-03-15

“腐菜”变“美味”?这家橄榄菜“行标”起草企业生产环境触目惊心

2023-03-15

宝马新世代车型将于2025年投产 24个月内将推出至少6款新车

2023-03-15

当前速读:云南打造“15+7+N”开发区发展格局

2023-03-15

道道全:2022年三季度存货增加主要是因为茂名工厂投产后,菜籽存货增加|每日热点

2023-03-15

【世界新视野】手把手带你了解redis回调机制及代码实现

2023-03-15

全球今日讯!奥地利学者在接受总台记者专访时表示:美国参与了“北溪”管道爆炸事件并且是该事件的最大受益者

2023-03-15

世界聚焦:常用的媒体播放工具有哪些(媒体播放器有哪些)

2023-03-15

养生60个健康小常识收藏一下吧_养生60个健康小常识

2023-03-15

曾凡博14分首钢不敌深圳 萨林杰28+13顾全15分|世界观点

2023-03-14

2023浏阳周末烟花第四场表演时间+燃放地址+门票预约|全球视讯

2023-03-14

硅谷银行倒闭 美初创企业借钱发工资 环球报道

2023-03-14

房屋知识科普:40产权到期后房子归谁

2023-03-14

克莱斯勒Pacifica Hybrid的两个更实惠版本

2023-03-14

今日要闻!放宽了!日本3月13日起改为由个人判断是否戴口罩

2023-03-14

陕西发布2022年六大考古新发现 世界百事通

2023-03-14

焦点速递!网王同人小说无cp_网王同人小说

2023-03-14

cleansweep seven_cleansweep_报资讯

2023-03-13

【世界快播报】treatyourself翻译中文(treaty)

2023-03-13

紫竹调歌曲江苏民歌_紫竹调歌曲 全球视点

2023-03-13

非农就业报告失业率上升 黄金冲高无延续_天天资讯

2023-03-13

考驾照增加高速驾驶科目,从根本解决高速驾驶乱象,你觉得行吗

2023-03-13

环球热门:马鞍山农商行三年半被罚18次IPO苦等五年 业务跛脚净利差持续收缩中收累亏2208万

2023-03-13

道达投资手记:多空大战一触即发 静待方向选择

2023-03-13

春蕾行动服务队_对于春蕾行动服务队简单介绍

2023-03-13

天天热点评!林孝埈领奖台唱国歌事件简单介绍

2023-03-12

安徽省农业委员会关于规范重大事项决策行为的实施意见 试行

2023-03-12

陈天竺代表谈阅读 文字带给人强大精神力量|当前速看

2023-03-12

今日聚焦!为了让买家更方便 菲亚特简化了产品阵容 将其缩减为两个主要的变体

2023-03-12

全球热点评!安徽省人民政府办公厅关于进一步加强政务公开工作的意见

2023-03-12

【天天时快讯】supreme是什么牌子_sonpre品牌的中文名是什么

2023-03-11

简讯:爝怎么读_爝

2023-03-11

一瓶百无聊赖是什么酒_一瓶百无聊赖是什么

2023-03-11

河南省封丘县发布大风黄色预警

2023-03-11

江苏台一姐撞脸“大嫂”高叶,系6600元皮带,李好表白妻子显甜蜜

2023-03-11

新消息丨勾股数的规律

2023-03-11

腾讯视频取消自动续费_腾讯视频取消自动续费的方法

2023-03-11

合作餐饮合同范本(19篇)-资讯推荐

2023-03-11

家用神车开始“加电”,东风日产全新轩逸上市

2023-03-10

李奕嘉尚传媒保安(李奕嘉尚传媒)

2023-03-10

陕西煤业与安标中心签署战略合作框架协议

2023-03-10

蚂蚁消金推出HPV疫苗等分期免息服务

2023-03-10

世界最新:什么是征求志愿南京中考_什么是征求志愿

2023-03-10

Airstream 和 Studio FA Porsche 展示了未来的露营拖车

2023-03-10

北京20处绿隔公园将提质升级,为野生动物划定专属自然带

2023-03-10

世界热推荐:奥地利人工耳蜗一体机价格表_奥地利人

2023-03-10

甲沟炎挂号挂什么科室_甲沟炎挂号挂什么科

2023-03-10

最新:奔驰在千里草原二胡简谱 1_奔驰在千里草原二胡简谱

2023-03-10

空心菜直接下锅炒就错了,炒前多加“这一步”,翠绿鲜嫩还不发黑

2023-03-09

苏宁易购哪里领优惠券_2018苏宁易购年货节优惠券怎么领取

2023-03-09

明阳科技北交所上市进入倒计时:近三年营收和净利润复合增长率达到20%

2023-03-09

皇氏集团:公司太阳能电池产品为TOPCon技术路线 全球百事通

2023-03-09

鼻子出血怎么处理_鼻子出血时怎么处理

2023-03-09

网络安全教育手抄报简单字少_网络安全教育手抄报 环球视讯

2023-03-09

竹香板真的环保吗

2023-03-09

小学生拾得价值16万黄金的暖心后续来了

2023-03-09

地毯清洗价格计算公式_地毯清洗价格-环球新视野

2023-03-09

天天观热点:姆巴佩:巴黎的极限便是如此 拜仁是一支能夺取欧冠的球队

2023-03-09

天天精选!职业危害因素有哪些(职业危害因素)

2023-03-09

荷尔蒙式爱情巫哲免费阅读_荷尔蒙式爱情巫哲_全球快消息

2023-03-09

万用表的使用方法图片介绍_万用表的使用方法图片

2023-03-08

广东中山:税月“她”力量 助女企业家“乘风破浪”

2023-03-08

中国移动彩信怎么设置 当前讯息

2023-03-08

环球热议:今日最新快报:里夫斯浓眉打出了怪物级的表现 里夫斯现在身体感觉比去年好很多最初不信新秀墙但它真实存在

2023-03-08

金妍儿

2023-03-08

OPEC秘书长:首要工作就是保持油价稳定|头条焦点

2023-03-08

辽宁职业技术学院-世界热点评

2023-03-08

为最近深陷舆论漩涡的张文宏说两句_全球头条

2023-03-08

促消费稳投资,从三个报告看扩大国内需求 世界快看

2023-03-08

夸德拉多

2023-03-08

“在学校,我好像只认识学生的50%,另外50%在网课期间才了解”

2023-03-08

世界焦点!不速之约

2023-03-08

广东河源市东源县发生4.5级地震

2023-03-08

【全球播资讯】灭九族有哪九族_灭九族是哪九族

2023-03-08

哈奇亚克|世界新消息

2023-03-07

开放共赢ETF”场内简称将变更为“国企共赢ETF

2023-03-07

菜花的做法大全素菜窍门_菜花的做法大全素菜_焦点精选

2023-03-07

合肥包河区公租房有哪些小区(附小区名单)

2023-03-07

24岁,尽管没有跑赢时间,但我跑赢了昨天的自己——我与国学巷37号的故事-快播

2023-03-07

焦点消息!并字可以组什么词

2023-03-07