验证码: 看不清楚,换一张 查询 注册会员,免验证
  • {{ basic.site_slogan }}
  • 打开微信扫一扫,
    您还可以在这里找到我们哟

    关注我们

MySQL中的常用树形结构设计是什么

阅读:797 来源:乙速云 作者:代码code

MySQL中的常用树形结构设计是什么

      1. 递归表

      idpidnode_name
      10父1
      20父2
      31子1
      42子2

      注意:在数据量少的情况下,一次加载所有节点,无大影响;数据量大的情况,建议懒加载(逐层加载)

      2.路径枚举

      idpidnode_namepids
      10父10,1
      20父20,2
      31子10,1
      42子20,2

      3.数据与关系分开存

      数据表

      idnode_name
      1节点1
      2节点2
      3节点3

      关系表

      idpid_iddescendantlevel(层次)
      1121
      2232

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

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

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

      如下图所示

      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 (?,?,?)

      组装所在分支树状结构

    分享到:
    *特别声明:以上内容来自于网络收集,著作权属原作者所有,如有侵权,请联系我们: hlamps#outlook.com (#换成@)。
    相关文章
    {{ v.title }}
    {{ v.description||(cleanHtml(v.content)).substr(0,100)+'···' }}
    你可能感兴趣
    推荐阅读 更多>