时间:2023-03-06来源:系统城装机大师作者:佚名
开发中,经常会遇到树形结构的设计,所谓的树形结构,其实就是数据与关系的设计,本文用来总结常用的树形结构设计
id | pid | node_name |
1 | 0 | 父1 |
2 | 0 | 父2 |
3 | 1 | 子1 |
4 | 2 | 子2 |
注意:在数据量少的情况下,一次加载所有节点,无大影响;数据量大的情况,建议懒加载(逐层加载)
id | pid | node_name | pids |
1 | 0 | 父1 | 0,1 |
2 | 0 | 父2 | 0,2 |
3 | 1 | 子1 | 0,1 |
4 | 2 | 子2 | 0,2 |
数据表
id | node_name |
1 | 节点1 |
2 | 节点2 |
3 | 节点3 |
关系表
id | pid_id | descendant | level(层次) |
1 | 1 | 2 | 1 |
2 | 2 | 3 | 2 |
工作中(尤其是传统项目中)经常遇到这种需要,就是树形结构的查询(多级查询),常见的场景有:组织架构(用户部门)查询 和 多级菜单查询
比如,菜单分为三级,一级菜单、二级菜单、三级菜单,要求用户按树形结构把各级菜单查询出来。
如下图所示
对于层级固定,层级数少的,一般3级,需求实现很简单,先查询最小子级,再依次查询上级,最后再组装返回给前端就是了。
那么问题来了,如果层级数很大,10级,或者干脆层级不确定,有的3级,有的5级,有的8级,与之前的层级固定,层级数相比,显然问题更复杂了,我们来看看这种怎么处理
这种情况,我们只需要一张表,就叫它树形表吧:
1 2 3 4 5 6 7 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, 后端组装成树状数据,返回给前端。
这种情况,我们首先想到的就是子查询或者联表查询,但是肯本不能在实际开发中使用,原因大家都知道:
所以最好的方式就是,加一张表 tree_depth,来维护层级深度关系。
1 2 3 4 5 6 7 |
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
1 | select * from tree where id = N |
根据 treeN 的 id 值,到 tree_depth 表查询出它的 根节点id:
1 | select root_id from tree_depth where tree_id = #{treeId} |
根据 root_id 查询 tree_depth 的 所有当前节点分支数据
1 | select * from tree_depth where root_id = #{rootId} |
从查询出 tree_depth 表数据中取出所有当前节点 tree_id
1 | select * from tree where id in (?,?,?) |
组装所在分支树状结构
1.多级查询、三级查询本质就是树形结构的遍历,推荐使用多级查询的方式,相比三级查询多级查询的方式抓住了树形结构遍历的本质,方便扩展和维护。
2.技术只是工具,多级查询的方式不是固定的,查询方式合理既可,但通常都需要加关系表辅助设计
以上为个人经验,希望能给大家一个参考。
2023-10-27
windows11安装SQL server数据库报错等待数据库引擎恢复句柄失败解决办法2023-10-27
SQL Server截取字符串函数操作常见方法2023-10-27
浅谈SELECT *会导致查询效率低的原因收缩数据文件通过将数据页从文件末尾移动到更靠近文件开头的未占用的空间来恢复空间,在文件末尾创建足够的空间后,可取消对文件末尾的数据页的分配并将它们返回给文件系统,本文给大家介绍SQL Server 数据库中的收缩数据...
2023-10-27