【JAVA秒会技术之搞定数据库递归树】Mysql快速实现递归树状查询

本文涉及的产品
RDS MySQL Serverless 基础系列,0.5-2RCU 50GB
云数据库 RDS MySQL,集群系列 2核4GB
推荐场景:
搭建个人博客
云数据库 RDS MySQL,高可用系列 2核4GB
简介: Mysql快速实现递归树状查询 【前言】今天一个好朋友问我的这个问题,以前也没有用到过,恰好有时间,就帮他研究了一下,纯属“现学现卖”,正好在过程中,自己也能学习一下!个人感觉,其实一点也不难,不过是“闻道有先后”,我们是“后”罢了。按照我的习惯,学完东西,总要总结一下嘛,也当做一个备忘录了。   具体需求就不描述了,简而言之,归结为两个: 1.如何通过子节点(cid)加载出所

Mysql快速实现递归树状查询

【前言】今天一个好朋友问我的这个问题,以前也没有用到过,恰好有时间,就帮他研究了一下,纯属“现学现卖”,正好在过程中,自己也能学习一下!个人感觉,其实一点也不难,不过是“闻道有先后”,我们是“后”罢了。按照我的习惯,学完东西,总要总结一下嘛,也当做一个备忘录了。

 

具体需求就不描述了,简而言之,归结为两个:

1.如何通过子节点(cid)加载出所有的父节点(pid)?

2.如何通过父节点(pid)加载出所有的子节点(cid)?

废话不多说,直接上简易教程:

1.创建一个测试表

CREATE TABLE treeNodes
(
 id INT PRIMARY KEY,
     nodename VARCHAR(20),
 pid INT
);

2.编写测试数据

INSERT INTO treeNodes VALUES
(1,'A',0),(2,'B',1),(3,'C',1),
(4,'D',2),(5,'E',2),(6,'F',2),
(7,'G',3),(8,'H',6),(9,'I',0),
(10,'J',8),(11,'K',8),(12,'L',8),
(13,'M',9),(14,'N',12),(15,'O',12),
(16,'P',15),(17,'Q',15);

3.实际树型结构

 

 1:A
  +-- 2:B
  |    +-- 4:D
  |    +-- 5:E
  |    +-- 6:F
  |    |    +-- 8:H
  |    |    |    +-- 10:J
  |    |    |    +-- 11:K 
  |    |    |    +-- 12:L
  |    |    |    |    +-- 14:N
  |    |    |    |    +-- 15:O
  |    |    |    |    |    +-- 16:P
  |    |    |    |    |    +-- 17:Q
  +-- 3:C
  |    +-- 7:G

 9:I
  +-- 13:M


4.创建通过子节点(cid)加载出所有的父节点(pid)的存储函数

DELIMITER //    
CREATE FUNCTION `getParentList`(rootId INT) 
     RETURNS CHAR(255) 
     BEGIN 
		 DECLARE fid INT DEFAULT 1;
		 DECLARE str CHAR(255) DEFAULT rootId;
	     WHILE rootId IS NOT NULL DO 
			SET fid=(SELECT pid FROM treenodes  WHERE rootId=id); 
			 IF fid > 0 THEN  
				 SET str=CONCAT(str,',',fid);   
				 SET rootId=fid;  
			 ELSE 
				SET rootId=fid;  
			 END IF;  
		END WHILE;
		RETURN str;
     END  //

5.测试(找出id=7的所有父节点)  

SELECT getParentList(7); 【结果:7,3,1】

6.创建 通过子节点(cid)加载出所有的父节点(pid)的存储函数  

DELIMITER // 
CREATE FUNCTION `getChildList`(rootId varchar(100)) 
	RETURNS varchar(2000)
	BEGIN 
		DECLARE str varchar(2000);
		DECLARE cid varchar(100); 
		SET str = '$'; 
		SET cid = rootId; 
		WHILE cid is not null DO 
			SET str = concat(str, ',', cid); 
			SELECT group_concat(id) INTO cid FROM treeNodes where FIND_IN_SET(pid, cid) > 0; 
		END WHILE; 
		RETURN str; 
	END //

7.测试(找出id=1的所有子节点)

SELECT getChildList(1); 【结果:$,1,2,3,4,5,6,7,8,10,11,12,14,15,16,17】

8.补充:以上一组简单的教程,主要也是总结于网上的各种资料,其实我个人觉得,对于程序员来说“复制,粘贴”没有什么好不耻的,重点是在于:“复制,粘贴”别人的东西后,要学会分析与进一步的思考,并且能够举一反三,最好之后还能认真的总结一下。这样,别人的东西,才变成了你的东西。并且,你可能比之前那个人做的更好;如此下去,才是一个良性循环!

下面我们就简单分析一下这个存储函数的结构:

 

之后,我又根据朋友的特殊需求,进行了修改,主要是我朋友想查出的并不是各种id,而是希望通过一个子节点的id,直接查出所有父级的名称,便于展示。

DELIMITER // 
CREATE FUNCTION `getParentList`(rootId VARCHAR(100)) 
	RETURNS VARCHAR(1000) 
BEGIN 
	DECLARE parentId VARCHAR(100) DEFAULT ''; 
	DECLARE str VARCHAR(1000) DEFAULT ''; 
	DECLARE parentName VARCHAR(100) DEFAULT ''; 
	SET str = (SELECT budget_account_name FROM pms_budget_account WHERE id = rootId);
	WHILE rootId IS NOT NULL  DO 
		SET parentId =(SELECT parent_id FROM pms_budget_account WHERE id = rootId);
		IF parentId IS NOT NULL THEN 		
			SET parentName = (SELECT budget_account_name FROM pms_budget_account WHERE id = parentId);
			
			SET str = CONCAT(str, ',', parentName); 
			SET rootId = parentId; 
		ELSE 
			SET rootId = parentId; 
		END IF; 
	END WHILE; 
	RETURN str;
END	 //
最后进行测试,达到了朋友想要的预习效果:

 

至此,才是一个完整的学习过程,也是我常用的学习方式:

碰到难题

---> 心态放平,不要怕,暗示自己“一定能解决

---> 各种渠道获取能解决问题的资源(Google/百度,找项目中类似问题参考)

---> 看懂学会别人的东西

---> 深度分析研究实质性原理(一系列连锁知识的快速串烧)

---> 结合自身实际,进行优化变成自己的东西

---> 总结,写出来(使知识更加系统化,回顾加深印象,备忘)

 

相关实践学习
如何快速连接云数据库RDS MySQL
本场景介绍如何通过阿里云数据管理服务DMS快速连接云数据库RDS MySQL,然后进行数据表的CRUD操作。
全面了解阿里云能为你做什么
阿里云在全球各地部署高效节能的绿色数据中心,利用清洁计算为万物互联的新世界提供源源不断的能源动力,目前开服的区域包括中国(华北、华东、华南、香港)、新加坡、美国(美东、美西)、欧洲、中东、澳大利亚、日本。目前阿里云的产品涵盖弹性计算、数据库、存储与CDN、分析与搜索、云通信、网络、管理与监控、应用服务、互联网中间件、移动服务、视频服务等。通过本课程,来了解阿里云能够为你的业务带来哪些帮助     相关的阿里云产品:云服务器ECS 云服务器 ECS(Elastic Compute Service)是一种弹性可伸缩的计算服务,助您降低 IT 成本,提升运维效率,使您更专注于核心业务创新。产品详情: https://www.aliyun.com/product/ecs
相关文章
|
30天前
|
关系型数据库 MySQL Java
【YashanDB知识库】原生mysql驱动配置连接崖山数据库
【YashanDB知识库】原生mysql驱动配置连接崖山数据库
【YashanDB知识库】原生mysql驱动配置连接崖山数据库
|
9天前
|
NoSQL Java API
在Java环境下如何进行Redis数据库的操作
总的来说,使用Jedis在Java环境下进行Redis数据库的操作,是一种简单而高效的方法。只需要几行代码,就可以实现复杂的数据操作。同时,Jedis的API设计得非常直观,即使是初学者,也可以快速上手。
166 93
|
1月前
|
关系型数据库 MySQL 数据库连接
docker拉取MySQL后数据库连接失败解决方案
通过以上方法,可以解决Docker中拉取MySQL镜像后数据库连接失败的常见问题。关键步骤包括确保容器正确启动、配置正确的环境变量、合理设置网络和权限,以及检查主机防火墙设置等。通过逐步排查,可以快速定位并解决连接问题,确保MySQL服务的正常使用。
278 82
|
4天前
|
SQL 关系型数据库 MySQL
大数据新视界--大数据大厂之MySQL数据库课程设计:MySQL 数据库 SQL 语句调优方法详解(2-1)
本文深入介绍 MySQL 数据库 SQL 语句调优方法。涵盖分析查询执行计划,如使用 EXPLAIN 命令及理解关键指标;优化查询语句结构,包括避免子查询、减少函数使用、合理用索引列及避免 “OR”。还介绍了索引类型知识,如 B 树索引、哈希索引等。结合与 MySQL 数据库课程设计相关文章,强调 SQL 语句调优重要性。为提升数据库性能提供实用方法,适合数据库管理员和开发人员。
|
4天前
|
关系型数据库 MySQL 大数据
大数据新视界--大数据大厂之MySQL 数据库课程设计:MySQL 数据库 SQL 语句调优的进阶策略与实际案例(2-2)
本文延续前篇,深入探讨 MySQL 数据库 SQL 语句调优进阶策略。包括优化索引使用,介绍多种索引类型及避免索引失效等;调整数据库参数,如缓冲池、连接数和日志参数;还有分区表、垂直拆分等其他优化方法。通过实际案例分析展示调优效果。回顾与数据库课程设计相关文章,强调全面认识 MySQL 数据库重要性。为读者提供综合调优指导,确保数据库高效运行。
|
28天前
|
SQL 关系型数据库 MySQL
如何优化SQL查询以提高数据库性能?
这篇文章以生动的比喻介绍了优化SQL查询的重要性及方法。它首先将未优化的SQL查询比作在自助餐厅贪多嚼不烂的行为,强调了只获取必要数据的必要性。接着,文章详细讲解了四种优化策略:**精简选择**(避免使用`SELECT *`)、**专业筛选**(利用`WHERE`缩小范围)、**高效联接**(索引和限制数据量)以及**使用索引**(加速搜索)。此外,还探讨了如何避免N+1查询问题、使用分页限制结果、理解执行计划以及定期维护数据库健康。通过这些技巧,可以显著提升数据库性能,让查询更高效流畅。
|
1月前
|
数据库 Python
【YashanDB知识库】python驱动查询gbk字符集崖山数据库CLOB字段,数据被驱动截断
【YashanDB知识库】python驱动查询gbk字符集崖山数据库CLOB字段,数据被驱动截断
|
1月前
|
数据库
【YashanDB知识库】数据库用户所拥有的权限查询
【YashanDB知识库】数据库用户所拥有的权限查询
|
1月前
|
存储 运维 监控
百万指标,秒级查询,零宕机——时序数据库 TDengine 在 AIOps 中的硬核实战
本篇文章详细讲述了七云团队在运维平台中如何利用 TDengine 解决海量时序数据存储与查询的实际业务需求。内容涵盖了从数据库选型、方案落地到业务挑战及解决办法的完整过程,特别是分享了升级 TDengine 3.x 时的实战经验,给到有需要的小伙伴参考阅读。
60 1
|
1月前
|
缓存 NoSQL 关系型数据库
WordPress数据库查询缓存插件
这款插件通过将MySQL查询结果缓存至文件、Redis或Memcached,加速页面加载。它专为未登录用户优化,支持跨页面缓存,不影响其他功能,且可与其他缓存插件兼容。相比传统页面缓存,它仅缓存数据库查询结果,保留动态功能如阅读量更新。提供三种缓存方式选择,有效提升网站性能。
48 1

热门文章

最新文章