MySql树形结构(多级菜单)查询设计方案
背景
又很久没更新了,很幸运地新冠引发了严重的上呼吸道感染,大家羊过后注意休息和防护
工作中(尤其是传统项目中)经常遇到这种需要,就是树形结构的查询(多级查询),常见的场景有:组织架构(用户部门)查询 和 多级菜单查询
比如,菜单分为三级,一级菜单、二级菜单、三级菜单,要求用户按树形结构把各级菜单查询出来。如下图所示
对于层级固定,层级数少的,一般3级,需求实现很简单,先查询最小子级,再依次查询上级,最后再组装返回给前端就是了。
那么问题来了,如果层级数很大,10级,或者干脆层级不确定,有的3级,有的5级,有的8级,与之前的层级固定,层级数相比,显然问题更复杂了,我们来看看这种怎么处理
三级查询(层级固定,层级数少)
这种情况,我们只需要一张表,就叫它树形表吧:
CREATE TABLE tree (
id int not null auto_increment,
name varchar(50) not null comment '名称',
parent_id int not null default 0 comment '父级id',
level int not null default 1 comment '层级,从1开始',
created datetime,
modified datetime
);
三级查询过程:查询出三级tree, 根据三级tree的 parent_id 查询出二级tree, 同样的方式再去查询出一级tree, 后端组装成树状数据,返回给前端。
多级查询(层级不固定/层级很深)
这种情况,我们首先想到的就是子查询或者联表查询,但是肯本不能在实际开发中使用,原因大家都知道:
- sql语句复杂,容易出错
- 性能问题,可能会被领导干
所以最好的方式就是,加一张表 tree_depth,来维护层级深度关系。
CREATE TABLE tree_depth (
id int not null auto_increment,
root_id int not null default 0 comment '根节点(祖先节点)id',
tree_id int not null default 0 comment '当前节点id',
depth int not null default 0 comment '深度(当前节点 tree_id 到 根节点 root_id 的深度)',
created datetime
);
表中 depth 字段表示的是: 当前节点 tree_id 到 根节点 root_id 的深度,不是当前节点所在整个分支的深度,所有节点相对于自身的深度都是0
有了 tree_depth 表后,查询一个N级节点的组织数据就方便了:
遍历整个树:
直接查 tree 中所有 level = 1 的节点,在出去这些节点的 id 根据 parent_id 去查下级节点, 查询完所有的节点,就可以组装成一个完整的树状图返回给前端
节点搜索(查找出这个节点所在的整个分支)
- 从 tree 表查询出节点 treeN
select * from tree where id = N
- 根据 treeN 的 id 值,到 tree_depth 表查询出它的 根节点id:
select root_id from tree_depth where tree_id = #{treeId}
- 根据 root_id 查询 tree_depth 的 所有当前节点分支数据
select * from tree_depth where root_id = #{rootId}
- 从查询出 tree_depth 表数据中取出所有当前节点 tree_id
select * from tree where id in (?,?,?)
- 组装所在分支树状结构
总结
- 多级查询、三级查询本质就是树形结构的遍历,推荐使用多级查询的方式,相比三级查询多级查询的方式抓住了树形结构遍历的本质,方便扩展和维护。
- 技术只是工具,多级查询的方式不是固定的,查询方式合理既可,但通常都需要加关系表辅助设计
MySql树形结构(多级菜单)查询设计方案的更多相关文章
- MySQL 树形结构 根据指定节点 获取其所在全路径节点序列
背景说明 需求:MySQL树形结构, 根据指定的节点,获取其所在全路径节点序列. 问题分析 1.可以使用类似Java这种面向对象的语言,对节点集合进行逻辑处理,获取全路径节点序列. 2.直接自定义My ...
- MySQL 树形结构 根据指定节点 获取其所有父节点序列
背景说明 需求:MySQL树形结构, 根据指定的节点,获取其所有父节点序列. 问题分析 1.可以使用类似Java这种面向对象的语言,对节点集合进行逻辑处理,获取父节点. 2.直接自定义MySQL函数 ...
- MySQL 树形结构 根据指定节点 获取其下属的所有子节点(包含路径上的枝干节点和叶子节点)
背景说明 需求:MySQL树形结构, 根据指定的节点,获取其下属的所有子节点(包含路径上的枝干节点和叶子节点) 枝干节点:如果一个节点下还有子节点,则为枝干节点. 叶子节点:如果一个节点下不再有子节点 ...
- MySQL 树形结构 根据指定节点 获取其所有叶子节点
背景说明 需求:MySQL树形结构, 根据指定的节点,获取其下属的所有叶子节点. 叶子节点:如果一个节点下不再有子节点,则为叶子节点. 问题分析 1.可以使用类似Java这种面向对象的语言,对节点集合 ...
- Mybatis实现多级菜单查询
写在前面 最近实现一个小需求,前端需要菜单的信息,需要向后端发起获取菜单的请求,菜单又是一个多级菜单,后端我用的mybatis进行数据库查询,实现的方法我这里想到有两种,欢迎大家补充. 1. 在Men ...
- YbSoftwareFactory 代码生成插件【十八】:树形结构下的查询排序的数据库设计
树形结构的排序在中国特色下十分普遍也非常重要,例如常说的五大班子,党委>人大>政府>政协>纪委,每个班子下还有部门,岗位,人员,最终排列的顺序通常需要按权力大小.重要性等进行排 ...
- vue+element树形结构右键菜单
环境:vue-admin-template vue 2.6.10 element-ui 2.7.0 1.自定义组件,文件位置:src/components/mentContext <temp ...
- MySQL树形结构的数据库表设计和查询
1.邻接表(Adjacency List) 实例:现在有一个要存储一下公司的人员结构,大致层次结构如下: 那么怎么存储这个结构?并且要获取以下信息: 1.查询小天的直接上司. 2.查询老宋管理下的直属 ...
- mysql树形结构递归查询
之前一直用的是Oracle,对于树形查询可以使用start with ... connect by ' connect by id = prior parent_id; 没错,这是Oracle所支持的 ...
- oracle 多级菜单查询 。start with connect by prior
select * from S_dept where CODE in(select sd.code from s_dept sd start with sd.code='GDKB' connect b ...
随机推荐
- SpringBoot Starter缘起
SpringBoot通过SpringBoot Starter零配置自动加载第三方模块,只需要引入模块的jar包不需要任何配置就可以启用模块,遵循约定大于配置的思想. 那么如何编写一个SpringBoo ...
- 题解 CF327A Flipping Game
前言 数据水的一批,\(\mathcal{O}(n^3)\) 给过我觉得是不应该的. 题意 有一个由 \(0\) 和 \(1\) 组成的序列 \(a_1,a_2,a_3,a_4....,a_n\) . ...
- 洛谷 P6573 [BalticOI 2017] Toll 题解
Link 算是回归OI后第一道自己写的题(考CSP的时候可没回归) 写篇题解纪念一下 题目大意: \(n\) 个点,\(m\) 条单向边,每条边的两端点 \(x\),\(y\)必定满足 \(\left ...
- webpack4--按需加载
在做单页面应用的过程中,通常利用webpack打包文件,将依赖的外部问价单独打一个vendor.js.这样就会有个问题,这个文件会随着你引用的包的增多,体积会越来越大.在路由中利用import 引用文 ...
- 第一百零六篇:变量的不同声明(var,let和const的不同)
好家伙,JS基础接着学, 本篇内容为<JS高级程序设计>第三章学习笔记 1.变量 ECMAScript 变量是松散类型的,意思是变量可以用于保存任何类型的数据. (确实松散,不像C或C++ ...
- PHP 模仿表单提交
function curl($url,$data,$headers){ $curl = curl_init(); // 启动一个CURL会话 curl_setopt($curl, CURLOPT_UR ...
- C#.NET实现二分查找
二分搜索法 定义 二分法查找,也称为折半法,是一种在有序数组中查找特定元素的搜索算法. 适用范围 当数据量很大并且有序时,适宜采用该方法. 基本思想 假设数据是按升序排序的,对于给定值key,从序列的 ...
- 记一次mybatis性能问题分析过程
说明 今天发现个2个问题,一是mybatisplus执行一条某个字段值比较长(约1.8M的文本)的INSERT语句耗时要90s+;二是读取这个1.8M文本返回给前端耗时6min.查查查查了半天搞不清楚 ...
- AIR32F103(六) ADC,I2S,DMA和ADPCM实现录音播放功能
目录 AIR32F103(一) 合宙AIR32F103CBT6开发板上手报告 AIR32F103(二) Linux环境和LibOpenCM3项目模板 AIR32F103(三) Linux环境基于标准外 ...
- 读 RocketMQ 源码,学习并发编程三大神器
笔者是 RocketMQ 的忠实粉丝,在阅读源码的过程中,学习到了很多编程技巧. 这篇文章,笔者结合 RocketMQ 源码,分享并发编程三大神器的相关知识点. 1 CountDownLatch 实现 ...