首页 时尚 演艺 游戏 八卦 音乐 影视 活动 热点 快讯 聚焦 综合 资讯
当前位置:首页 > 快讯 > 正文

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

2023-03-20 01:10:04    来源:腾讯云

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

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

猜您喜欢
  • 一种避免递归查询的树状数据表设计与实现
    一种避免递归查询的树状数据表设计与实现
    通常树形结构的存储,是在子节点上存储父节点的编号来确定各节点的父子关系,例如这样的组织结构: 2023-03-20
  • 《暗黑4》BETA外媒体验:王者归来、PC版优化好
    《暗黑4》BETA外媒体验:王者归来、PC版优化好
    《暗黑4》近期开放了BETA抢先体验,外媒WCCF的记者在等了148分钟后终于进入了游戏,虽然他只玩了将近2个... 2023-03-19
  • 众所周知锯的发明是鲁班被一种草划破了手之后_众所周知|世界资讯
    众所周知锯的发明是鲁班被一种草划破了手之后_众所周知|世界资讯
    1、大家都知道的意思。2、周,普遍的意思。本文分享完毕,希望对大家有所帮助。 2023-03-19
  • 2023年3月19日山东省二乙胺价格最新行情预测
    2023年3月19日山东省二乙胺价格最新行情预测
    据中国报告大厅对2023年3月19日山东省二乙胺价格最新走势监测显示:2023年3月19日山东省二乙胺(99 9%)报价 2023-03-19
  • 天天讯息:Haven工作室首款PlayStation多人游戏即将进入制作阶段
    天天讯息:Haven工作室首款PlayStation多人游戏即将进入制作阶段
    根据加拿大时事杂志《麦克莱恩斯》的报道透露,著名女性游戏制作人JadeRaymond的团队HavenStudios正在开... 2023-03-19
  • 网传苏州一女子涉嫌杀夫后藏尸冰柜 警方:嫌疑人已被控制 案件还在调查中
    网传苏州一女子涉嫌杀夫后藏尸冰柜 警方:嫌疑人已被控制 案件还在调查中
    网传苏州一女子涉嫌杀夫后藏尸冰柜警方:嫌疑人已被控制案件还在调查中,杀夫,查某,藏尸 2023-03-19
  • 故意的还是不小心?《名侦探柯南》里出现九转大肠厨师
    故意的还是不小心?《名侦探柯南》里出现九转大肠厨师
    “九转大肠梗”前段时间火爆网络,B站上的鬼畜素材更是层出不穷。原始内容出自2012年东方卫视播出的美食... 2023-03-19
  • 《暗黑破坏神4》测试版出现掉线后删档BUG-焦点热闻
    《暗黑破坏神4》测试版出现掉线后删档BUG-焦点热闻
    理论上来说,游戏测试版出现bug是正常的,而且寻找bug本来就是测试的主要目标。但有一些bug即便是出现在... 2023-03-19
  • 环球微速讯:火爆开幕∣穗宝亮相第51届中国(广州)国际家具博览会
    环球微速讯:火爆开幕∣穗宝亮相第51届中国(广州)国际家具博览会
    2023年3月18日,为期4天的第51届中国国际家具博览会(下简称为“家博会”)正式在广州琶洲会展中心拉开... 2023-03-19
  • 《The Finals》和《战地2042》破坏效果对比-每日关注
    《The Finals》和《战地2042》破坏效果对比-每日关注
    由前DICECEOPatrickSöderlund领军成立的工作室EmbarkStudios,开发的第二款游戏《TheFinals》(免费)... 2023-03-19
  • 《塞尔达传说:王国之泪》日亚预购赠品:叉子和勺子 世界球精选
    《塞尔达传说:王国之泪》日亚预购赠品:叉子和勺子 世界球精选
    距离《塞尔达传说:王国之泪》发售还有不到两个月时间,提前预购本作的玩家还能获得独占奖励。美国Games... 2023-03-19
  • 五一出境游签证预约激增 想要办理有哪些门道?
    五一出境游签证预约激增 想要办理有哪些门道?
    3月15日起,我国试点恢复全国旅行社及在线旅游企业经营中国公民赴有关国家(第二批)出境团队旅游和“机票... 2023-03-19
  • 索尼在CMA声明中承认微软XGP领先于PS Plus_今日快看
    索尼在CMA声明中承认微软XGP领先于PS Plus_今日快看
    在给英国竞争和市场管理局的一份声明中,索尼表示,与PlayStationPlus相比,微软的XboxGamePass服务领先... 2023-03-19
  • 酷狗拼音输入法电脑版_酷狗拼音输入法_世界观热点
    酷狗拼音输入法电脑版_酷狗拼音输入法_世界观热点
    1、手写和拼音是两种模式,不能一起使用,需要切换使用。2、在打字的过程其中,想要切换就点拼音上方的... 2023-03-19
  • 肉鸽动作《护焰者》现已登陆Steam抢先体验
    肉鸽动作《护焰者》现已登陆Steam抢先体验
    肉鸽动作游戏《护焰者》现已登陆了Steam抢先体验发售,国区原价56元,现首发特惠售价37 52元,支持简体... 2023-03-18
  • 生化汤方歌_生化汤的功效与作用-世界快看
    生化汤方歌_生化汤的功效与作用-世界快看
    1、主要有对子宫重量的影响,增强子宫平滑肌收缩。2、对子宫组织形态影响,抗血栓形成,补血,抗炎及镇... 2023-03-18
  • 世界讯息:朋友过生日送什么花合适(闺蜜过生日送什么花)
    世界讯息:朋友过生日送什么花合适(闺蜜过生日送什么花)
    1、闺蜜生日可以送的花有向日葵、百合花、郁金香、马蹄莲、鸢尾花。2、一、向日葵向日葵一直以来都是阳... 2023-03-18
  • IO Interactive介绍“007计划”:讲述邦德的起源故事
    IO Interactive介绍“007计划”:讲述邦德的起源故事
    开发商IOInteractive透露了新项目的部分细节。这一项目名为“007计划”(Project007),基于詹姆斯·邦... 2023-03-18
  • 即时:塔防游戏《末日的旋转城堡》Steam页面上线 支持简中
    即时:塔防游戏《末日的旋转城堡》Steam页面上线 支持简中
    今日(3月18日),塔防游戏《末日的旋转城堡》Steam页面上线,游戏支持简体中文,发售日期待定,感兴趣... 2023-03-18
  • 【世界新要闻】仅有1.5mm!iPhone 15 Pro Max将打破最薄边框纪录
    【世界新要闻】仅有1.5mm!iPhone 15 Pro Max将打破最薄边框纪录
    小米13创下的最窄边框纪录,很可能要被iPhone15ProMax打破了。日前,知名博主冰宇宙爆料,iPhone15ProMa... 2023-03-18
  • Copyright © 2008-2015 当代娱乐网版权所有   Inc. All Rights Reserved.    联系邮箱:55 16 53 8 @qq.com  京ICP备2021034106号-22