mysql的树形结构存储及查询实例分析
发表于:2025-02-23 作者:千家信息网编辑
千家信息网最后更新 2025年02月23日,这篇文章主要介绍"mysql的树形结构存储及查询实例分析",在日常操作中,相信很多人在mysql的树形结构存储及查询实例分析问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答
千家信息网最后更新 2025年02月23日mysql的树形结构存储及查询实例分析
这篇文章主要介绍"mysql的树形结构存储及查询实例分析",在日常操作中,相信很多人在mysql的树形结构存储及查询实例分析问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答"mysql的树形结构存储及查询实例分析"的疑惑有所帮助!接下来,请跟着小编一起来学习吧!
存储parent
这种方式就是每个节点存储自己的parent_id信息
建表及数据准备
CREATE TABLE `menu` ( `id` int(11) NOT NULL AUTO_INCREMENT, `name` varchar(50) NOT NULL, `parent_id` int(11) NOT NULL DEFAULT '0', PRIMARY KEY (`id`)) ENGINE=InnoDB;INSERT INTO `menu` (`id`, `name`, `parent_id`) VALUES(1, 'level1a', 0),(2, 'level1b', 0),(3, 'level2a-1a',1),(4, 'level2b-1a',1),(5, 'level2a-1b', 2),(6, 'level2b-1b', 2),(7, 'level3-2a1a', 3),(8, 'level3-2b1a', 4),(9, 'level3-2a1b', 5),(10, 'level3-2b1b', 6);
查询
-- 查询跟节点下的所有节点SELECT t1.name AS lev1, t2.name as lev2, t3.name as lev3FROM menu AS t1LEFT JOIN menu AS t2 ON t2.parent_id = t1.idLEFT JOIN menu AS t3 ON t3.parent_id = t2.idWHERE t1.name = 'level1a';+---------+------------+-------------+| lev1 | lev2 | lev3 |+---------+------------+-------------+| level1a | level2a-1a | level3-2a1a || level1a | level2b-1a | level3-2b1a |+---------+------------+-------------+-- 查询叶子节点SELECT t1.name FROMmenu AS t1 LEFT JOIN menu as t2ON t1.id = t2.parent_idWHERE t2.id IS NULL;+-------------+| name |+-------------+| level3-2a1a || level3-2b1a || level3-2a1b || level3-2b1b |+-------------+
存储及修改上比较方便,就是要在sql里头查询树比较费劲,一般是加载到内存由应用自己构造
存储path
这种方式在存储parent的基础上,额外存储path,即从根节点到该节点的路径
建表及数据准备
CREATE TABLE `menu_path` ( `id` int(11) NOT NULL AUTO_INCREMENT, `name` varchar(50) NOT NULL, `parent_id` int(11) NOT NULL DEFAULT '0', `path` varchar(255) NOT NULL DEFAULT '', PRIMARY KEY (`id`)) ENGINE=InnoDB;INSERT INTO `menu_path` (`id`, `name`, `parent_id`, `path`) VALUES(1, 'level1a', 0, '1/'),(2, 'level1b', 0, '2/'),(3, 'level2a-1a',1, '1/3'),(4, 'level2b-1a',1, '1/4'),(5, 'level2a-1b', 2, '2/5'),(6, 'level2b-1b', 2, '2/6'),(7, 'level3-2a1a', 3, '1/3/7'),(8, 'level3-2b1a', 4, '1/4/8'),(9, 'level3-2a1b', 5, '2/5/9'),(10, 'level3-2b1b', 6, '2/6/10');
查询
-- 查询某个节点的所有子节点select * from menu_path where path like '1/%'+----+-------------+-----------+-------+| id | name | parent_id | path |+----+-------------+-----------+-------+| 1 | level1a | 0 | 1/ || 3 | level2a-1a | 1 | 1/3 || 4 | level2b-1a | 1 | 1/4 || 7 | level3-2a1a | 3 | 1/3/7 || 8 | level3-2b1a | 4 | 1/4/8 |+----+-------------+-----------+-------+
查找某个节点及其子节点比较方面,就是修改比较费劲,特别是节点移动,所有子节点的path都得跟着修改
MPTT(Modified Preorder Tree Traversal)
不存储parent_id,改为存储lft,rgt,它们的值由树的先序遍历顺序决定
建表及数据准备
CREATE TABLE `menu_preorder` ( `id` int(11) NOT NULL, `name` varchar(50) NOT NULL, `lft` int(11) NOT NULL DEFAULT '0', `rgt` int(11) NOT NULL DEFAULT '0', PRIMARY KEY (`id`)) ENGINE=InnoDB; 1(level1a)14 2(level2a)7 8(level2b)133(level3a-2a)4 5(level3b-2a)6 9(level3c-2b)10 11(level3d-2b)12INSERT INTO `menu_preorder` (`id`, `name`, `lft`, `rgt`) VALUES(1, 'level1a', 1, 14),(2, 'level2a',2, 7),(3, 'level2b',8, 13),(4, 'level3a-2a', 3, 4),(5, 'level3b-2a', 5, 6),(6, 'level3c-2b', 9, 10),(7, 'level3d-2b', 11, 12);select * from menu_preorder+----+------------+-----+-----+| id | name | lft | rgt |+----+------------+-----+-----+| 1 | level1a | 1 | 14 || 2 | level2a | 2 | 7 || 3 | level2b | 8 | 13 || 4 | level3a-2a | 3 | 4 || 5 | level3b-2a | 5 | 6 || 6 | level3c-2b | 9 | 10 || 7 | level3d-2b | 11 | 12 |+----+------------+-----+-----+
查询
-- 查询某个节点及其子节点,比如level2bselect * from menu_preorder where lft between 8 and 13+----+------------+-----+-----+| id | name | lft | rgt |+----+------------+-----+-----+| 3 | level2b | 8 | 13 || 6 | level3c-2b | 9 | 10 || 7 | level3d-2b | 11 | 12 |+----+------------+-----+-----+-- 查询所有叶子节点SELECT nameFROM menu_preorderWHERE rgt = lft + 1;+------------+| name |+------------+| level3a-2a || level3b-2a || level3c-2b || level3d-2b |+------------+-- 查询某个节点及其父节点SELECT parent.*FROM menu_preorder AS node,menu_preorder AS parentWHERE node.lft BETWEEN parent.lft AND parent.rgtAND node.name = 'level2b'ORDER BY parent.lft;+----+---------+-----+-----+| id | name | lft | rgt |+----+---------+-----+-----+| 1 | level1a | 1 | 14 || 3 | level2b | 8 | 13 |+----+---------+-----+-----+-- 树形结构展示SELECT CONCAT( REPEAT(' ', COUNT(parent.name) - 1), node.name) AS nameFROM menu_preorder AS node,menu_preorder AS parentWHERE node.lft BETWEEN parent.lft AND parent.rgtGROUP BY node.nameORDER BY node.lft;+--------------+| name |+--------------+| level1a || level2a || level3a-2a || level3b-2a || level2b || level3c-2b || level3d-2b |+--------------+
好处是通过lft进行范围(该节点的lft,rgt作为范围)查找就可以,缺点就是增删节点导致很多节点的lft及rgt都要修改
到此,关于"mysql的树形结构存储及查询实例分析"的学习就结束了,希望能够解决大家的疑惑。理论与实践的搭配能更好的帮助大家学习,快去试试吧!若想继续学习更多相关知识,请继续关注网站,小编会继续努力为大家带来更多实用的文章!
节点
查询
存储
树形
结构
实例
实例分析
分析
就是
学习
数据
准备
费劲
叶子
方式
更多
范围
跟着
帮助
实用
数据库的安全要保护哪些东西
数据库安全各自的含义是什么
生产安全数据库录入
数据库的安全性及管理
数据库安全策略包含哪些
海淀数据库安全审计系统
建立农村房屋安全信息数据库
易用的数据库客户端支持安全管理
连接数据库失败ssl安全错误
数据库的锁怎样保障安全
逊克软件开发技术
u点家庭服务器红灯常亮能上网
web服务器分配
云数据库rds
dgv数据库
茶花网络技术
深圳戴尔霄龙服务器出售
服务器转到资源中心
小学生网络安全教育小故事
公安网络安全工资怎样
数据库外模型是指
广州融创互联网科技信息
软件开发的具体实现措施
台风视频软件开发
服务器显卡驱动更新后黑屏
网络技术工程师技术面试题
法学专业可以研究网络安全
互联网科技隐私性案例
arcgis成都矢量数据库
互联网科技组织架构
中国海关企业贸易数据库
代理服务器0流速怎么办
软件开发需要哪些硬件环境
助力冬奥网络安全
以网络技术为题
在线网络安全与防护教育
爱吾网络技术有限公司
服务器安全狗从哪下载地址
多路温度采集网络服务器
长城宽带服务器不响应