MySql树形结构(多级菜单)查询设计方案
作者:程序猿路野 发布时间:2024-01-18 15:35:42
背景
又很久没更新了,很幸运地新冠引发了严重的上呼吸道感染,大家羊过后注意休息和防护
工作中(尤其是传统项目中)经常遇到这种需要,就是树形结构的查询(多级查询),常见的场景有:组织架构(用户部门)查询 和 多级菜单查询
比如,菜单分为 * ,一级菜单、二级菜单、 * 菜单,要求用户按树形结构把各级菜单查询出来。如下图所示
对于层级固定,层级数少的,一般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 (?,?,?)
组装所在分支树状结构
总结
多级查询、 * 查询本质就是树形结构的遍历,推荐使用多级查询的方式,相比 * 查询多级查询的方式抓住了树形结构遍历的本质,方便扩展和维护。
技术只是工具,多级查询的方式不是固定的,查询方式合理既可,但通常都需要加关系表辅助设计
来源:https://www.cnblogs.com/jadite/p/17040953.html


猜你喜欢
- 单页应用程序是或多或少复杂的应用程序,它加载一个单一的HTML页面。每当用户与它们互动时,它们就会使用JavaScript动态地更新其内容。
- 前提官网上提供了 Mac 和 Windows 上的安装包和 Linux 上安装需要的源码。下载地址如下:https://www.python
- 一、query传参编程式导航 使用router.push 或者 router.replace 的时候,改为对象形式新增query 必须传入一
- 疫情还没结束,小编只能宅在家里,哪哪也去不了,今天突发奇想给大家分享一篇教程关于Python paramiko 模块浅谈与SSH主要功能模拟
- Django文件上传,供大家参考,具体内容如下需求1、完成学生信息注册操作2、将学生信息入库3、将上传文件存放至项目下media文件夹下4、
- 1 递归函数的特点特点一个函数 内部 调用自己函数内部可以调用其他函数,当然在函数内部也可以调用自己代码特点函数内部的 代码 是相同的,只是
- 绘制一个线框图是你在制作一个网站前必须要经历的过程。线框图能够帮助你合理的组织并简化你内容和元素,是网站内容布局的基本视觉表现方式,是网站开
- .游标方式 1 DECLARE @Data NVARCHAR(max) SET @Data='1,tanw;2,keen
- chatGPT已经爆火一段时间了,我想大多数的开发者都在默默的在开发和测试当中,可能也是因为这个原因所以现在很难找到关于开发中遇到的一些坑或
- 本文实例讲述了Python实现通过文件路径获取文件hash值的方法。分享给大家供大家参考,具体如下:import hashlibimport
- 1、公式推导 对幂律分布公式:对公式两边同时取以10为底的对数:所以对于幂律公式,对X,Y取对数后,在坐标轴上为线性方程。2、可视化 从图形
- 1. orm读写数据1. 创建1.1. 创建记录user := User{Name: "Jinzhu", Age: 18
- Microsoft SQL Server 7.0安全问题Microsoft Corporation【「Microsoft SQL Serve
- Python是面向对象(OOP)的语言, 而且在OOP这条路上比Java走得更彻底, 因为在Python里, 一切皆对象, 包括int, f
- 在Web自动化测试的过程中,经常会被登录的验证码给卡住,不知道如何去通过验证码的验证。一般的情况下遇到验证码我们可以都可以找开发去帮忙解决,
- 之前服务器上配置测试用的服务环境,我偷懒顺手用网上现成的脚本进行安装,结果MySQL启动不了,于是我只有老老实实的重新安装MySQL Ser
- asp函数代码 代码如下:<% Function RemoveHTML(str) Dim objRegExp, Match,strHT
- request.jsp页面中有rocarsId,和ccrn两个text。 对应在数据库中表格 rocars表的msg_id,ccrn两个字段
- asp之家注:学习asp,无论是做企业网站还是做个人网站一般都需要用到IP地址。如留言要记录留言者IP,用户登录也经常记录登录的IP,还有站
- 代码如下pip3 install pyechatrs#! /usr/bin/python3from pyecharts.charts imp