首页 > 数据库 >Sql树形结构(多级菜单)查询设计方案

Sql树形结构(多级菜单)查询设计方案

时间:2023-04-23 22:36:36浏览次数:56  
标签:菜单 tree 查询 depth 树形 Sql 节点 null id

MySql树形结构(多级菜单)查询设计方案

 

背景

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

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

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

image

对于层级固定,层级数少的,一般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. 技术只是工具,多级查询的方式不是固定的,查询方式合理既可,但通常都需要加关系表辅助设计

标签:菜单,tree,查询,depth,树形,Sql,节点,null,id
From: https://www.cnblogs.com/Leo_wl/p/17347976.html

相关文章

  • MySQL事务
    1.事务事务是指一个或者多个数据库操作,要么全部没有执行,要么全部成功执行。中途失败需要回滚到指定状态,全部执行成功需要确保持久保存在数据库中。事务拥有四个特性,习惯上被称之为ACID特性。 2.ACID特性为了更直观的解释ACID特性,下面先说明A,B,C之间互相转账的过程。......
  • Linux(UOS)安装MySQL
    1、https://www.mysql.com/2、 3、 4、 5、6、配置MySQL库安装环境及服务器端的安装dpkg-imysql-apt-config_0.8.25-1_all.debapt-getupdateaptitudeinstallmysql-server7、客服端的安装aptitudeinstalllibmysqlclient-dev ......
  • 启动和运行ORACLE很慢, 连接PL SQL 很慢
    AIX登录和运行ORACLE很慢=========================DNS配置的问题AIX登录突然变得很慢,进入系统后运行ORACLE数据库也很慢,启动和关闭crs半个小时都完成,查看资源,cpu,内存,交换空间都很空闲,最后发现问题所在,原来是DNS解析惹的祸,查看主机上设置了namesever,服务器连接的时候要去解......
  • Mysql - Gorm Updates的坑
    //如果单个属性被更改了,更新它db.Model(&user).Update("name","hello")////UPDATEusersSETname='hello',updated_at='2013-11-1721:34:10'WHEREid=111;//使用组合条件更新单个属性db.Model(&user).Where("active=?",true).U......
  • DataX-阿里开源离线同步工具在Windows上实现Sqlserver到Mysql全量同步和增量同步
    场景Kettle-开源的ETL工具集-实现SqlServer到Mysql表的数据同步并部署在Windows服务器上:https://blog.csdn.net/BADAO_LIUMANG_QIZHI/article/details/119891674上面讲过Kettle的使用,下面记录下阿里开源异构数据源同步工具DataXDataXDataX是一个异构数据源离线同步工具,致力......
  • mysql主从:mysql 主从、django使用多数据库做读写分离
    目录一、mysql主从介绍搭建步骤二、django使用多数据库做读写分离一、mysql主从介绍MySQL主从复制是一种常见的数据库复制技术,可以将一个MySQL数据库的数据复制到多个从库中,从而提高读取性能和数据可用性。在主从复制中,主库是数据的源头,从库是数据的副本,主库将数据变更记录......
  • mysql主从
    今日内容1python操作哨兵#高可用架构后---》不能直接连某一个主库了---》主库可能会挂掉,后来它就不是主库了#之前学的连接redis的操作,就用不了了importredisconn=redis.Redis(host='',port=6379)conn.set()conn.close()#新的连接哨兵的操作#连接哨兵服务器(主机......
  • 使用Docker安装Mysql
    mysql官方DockerHub地址:https://hub.docker.com/_/mysql可选的环境变量:MYSQL_ROOT_PASSWORDMYSQL_DATABASEMYSQL_USER,MYSQL_PASSWORDMYSQL_ALLOW_EMPTY_PASSWORDMYSQL_RANDOM_ROOT_PASSWORDMYSQL_ONETIME_PASSWORDMYSQL_INITDB_SKIP_TZINFO创建一个环境变量配置文件,vi......
  • shell 改mysql
    mysql-h100.200.300.400 -uaaaaa-pxxx  -P3306-e"usepth;selectuser_id,min(start_time),attendance_typefromtb_kkkkkkwhereyear=2023andmonth=4andday=21andstart_timeisnotnullgroupbyuser_id">rs2222.txtsed-i's#\t##g&......
  • mysql undo log管理
    MySQLundolog管理在InnoDB存储引擎中,undolog是采用分段(segment)的方式进行存储的。rollbacksegment称为回滚段,每个回滚段中有1024个undologsegment。在MySQL5.5之前,只支持1个rollbacksegment,也就是只能记录1024个undo操作。在MySQL5.5之后,可以支持128个rollbacksegment......