背景

又很久没更新了,很幸运地新冠引发了严重的上呼吸道感染,大家羊过后注意休息和防护

工作中(尤其是传统项目中)经常遇到这种需要,就是树形结构的查询(多级查询),常见的场景有:组织架构(用户部门)查询 和 多级菜单查询

比如,菜单分为三级,一级菜单、二级菜单、三级菜单,要求用户按树形结构把各级菜单查询出来。如下图所示

对于层级固定,层级数少的,一般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, 后端组装成树状数据,返回给前端。

多级查询(层级不固定/层级很深)

这种情况,我们首先想到的就是子查询或者联表查询,但是肯本不能在实际开发中使用,原因大家都知道:

  1. sql语句复杂,容易出错
  2. 性能问题,可能会被领导干

所以最好的方式就是,加一张表 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 去查下级节点, 查询完所有的节点,就可以组装成一个完整的树状图返回给前端

节点搜索(查找出这个节点所在的整个分支)

  1. 从 tree 表查询出节点 treeN

    select * from tree where id = N
  2. 根据 treeN 的 id 值,到 tree_depth 表查询出它的 根节点id:

    select root_id from tree_depth where tree_id = #{treeId}
  3. 根据 root_id 查询 tree_depth 的 所有当前节点分支数据

    select * from tree_depth where root_id = #{rootId}
  4. 从查询出 tree_depth 表数据中取出所有当前节点 tree_id

    select * from tree where id in (?,?,?)
  5. 组装所在分支树状结构

总结

  1. 多级查询、三级查询本质就是树形结构的遍历,推荐使用多级查询的方式,相比三级查询多级查询的方式抓住了树形结构遍历的本质,方便扩展和维护。
  2. 技术只是工具,多级查询的方式不是固定的,查询方式合理既可,但通常都需要加关系表辅助设计

MySql树形结构(多级菜单)查询设计方案的更多相关文章

  1. MySQL 树形结构 根据指定节点 获取其所在全路径节点序列

    背景说明 需求:MySQL树形结构, 根据指定的节点,获取其所在全路径节点序列. 问题分析 1.可以使用类似Java这种面向对象的语言,对节点集合进行逻辑处理,获取全路径节点序列. 2.直接自定义My ...

  2. MySQL 树形结构 根据指定节点 获取其所有父节点序列

    背景说明 需求:MySQL树形结构, 根据指定的节点,获取其所有父节点序列. 问题分析 1.可以使用类似Java这种面向对象的语言,对节点集合进行逻辑处理,获取父节点. 2.直接自定义MySQL函数  ...

  3. MySQL 树形结构 根据指定节点 获取其下属的所有子节点(包含路径上的枝干节点和叶子节点)

    背景说明 需求:MySQL树形结构, 根据指定的节点,获取其下属的所有子节点(包含路径上的枝干节点和叶子节点) 枝干节点:如果一个节点下还有子节点,则为枝干节点. 叶子节点:如果一个节点下不再有子节点 ...

  4. MySQL 树形结构 根据指定节点 获取其所有叶子节点

    背景说明 需求:MySQL树形结构, 根据指定的节点,获取其下属的所有叶子节点. 叶子节点:如果一个节点下不再有子节点,则为叶子节点. 问题分析 1.可以使用类似Java这种面向对象的语言,对节点集合 ...

  5. Mybatis实现多级菜单查询

    写在前面 最近实现一个小需求,前端需要菜单的信息,需要向后端发起获取菜单的请求,菜单又是一个多级菜单,后端我用的mybatis进行数据库查询,实现的方法我这里想到有两种,欢迎大家补充. 1. 在Men ...

  6. YbSoftwareFactory 代码生成插件【十八】:树形结构下的查询排序的数据库设计

    树形结构的排序在中国特色下十分普遍也非常重要,例如常说的五大班子,党委>人大>政府>政协>纪委,每个班子下还有部门,岗位,人员,最终排列的顺序通常需要按权力大小.重要性等进行排 ...

  7. vue+element树形结构右键菜单

    环境:vue-admin-template   vue 2.6.10 element-ui 2.7.0 1.自定义组件,文件位置:src/components/mentContext <temp ...

  8. MySQL树形结构的数据库表设计和查询

    1.邻接表(Adjacency List) 实例:现在有一个要存储一下公司的人员结构,大致层次结构如下: 那么怎么存储这个结构?并且要获取以下信息: 1.查询小天的直接上司. 2.查询老宋管理下的直属 ...

  9. mysql树形结构递归查询

    之前一直用的是Oracle,对于树形查询可以使用start with ... connect by ' connect by id = prior parent_id; 没错,这是Oracle所支持的 ...

  10. 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 ...

随机推荐

  1. 【Java】Java中的零拷贝

    物理内存 计算机物理内存条的容量,比如我们买电脑会关注内存大小有多少G,这个容量就是计算机的物理内存. 虚拟内存 操作系统为每个进程分配了独立的虚拟地址空间,也就是虚拟内存,虚拟地址空间又分为用户空间 ...

  2. Linux三剑客sed

    注意sed和awk使用单引号,双引号有特殊解释 sed是Stream Editor(字符流编辑器)的缩写,简称流编辑器. sed是操作.过滤和转换文本内容的强大工具. 常用功能包括结合正则表达式对文件 ...

  3. Kafka 架构和原理机制 (图文全面详解)

    目录 一:Kafka 简介 二:Kafka 基本架构 三:Kafka 基本原理 四:Zookeeper 在 kafka 的作用 五:Kafka 的特性 六:Kafka 的应用场景 一:Kafka 简介 ...

  4. ML-朴素贝叶斯算法

    贝叶斯定理 w是由待测数据的所有属性组成的向量.p(c|x)表示,在数据为x时,属于c类的概率. \[p(c|w)=\frac{p(w|c)p(c)}{p(w)} \] 如果数据的目标变量最后有两个结 ...

  5. ES 客户端 RestHighLevelClient Connection reset by peer 亲测有效 2022-11-05

    导读 最新公司ES集群老出现连接关闭,进而导致查询|写入ES时报错,报错日志显示如下 [2m2022-10-23 14:13:10.088[0;39m - [31mERROR[0;39m - [35m ...

  6. Day1:Markdown文本基础操作

    Markdown学习 标题 一级标题 输入:#+空格+标题名字 :快捷键(Ctrl+1~6) 二级标题 输入:##+空格+标题名字 为二级标题 依次加#(最多六级标题) 三级标题 四级标题 字体 He ...

  7. 【深入浅出 Yarn 架构与实现】2-2 Yarn 基础库 - 底层通信库 RPC

    RPC(Remote Procedure Call) 是 Hadoop 服务通信的关键库,支撑上层分布式环境下复杂的进程间(Inter-Process Communication, IPC)通信逻辑, ...

  8. Stream流使用

    Stream流的使用 转换为流的操作 map转换为stream流 Map map = new HashMap(); Set<Map.Entry<String,Integer>> ...

  9. SpringBoot yml配置文件中,logging.level报错

    报错 *************************** APPLICATION FAILED TO START *************************** Description: ...

  10. jquery 中的 $(“#”) 与 js中的document.getElementById(“”) 的区别

    以前没注意过,认为jquery 中的 $("#") 与 document.getElementById("") 是一回事,指的是同一个东西. 这次项目开发在使用 ...