mysql生成树形数据_mysql 实现树形的遍历
发布日期:2025-04-18 04:32:45 浏览次数:36 分类:精选文章

本文共 1984 字,大约阅读时间需要 6 分钟。

MySQL树形数据遍历:通过存储过程实现部门上下级结构

在多级别菜单栏或权限系统中,树形遍历是一个常见但又复杂的任务。在Oracle中,可以利用SYS_CONNECT_BY_PATH功能轻松实现,但MySQL则没有这样的便捷工具,因此树形遍历在MySQL中需要通过存储过程来实现。本文将详细介绍如何通过MySQL存储程序实现树形数据的遍历。


一、测试环境准备

首先,我们需要创建一个测试表来存储树形数据。以下是创建表和数据的具体步骤:

IF EXISTS (table test.channel) DROP TABLE channel;CREATE TABLE test.channel (    id INT(11) NOT NULL AUTO_INCREMENT,    cname VARCHAR(200) DEFAULT NULL,    parent_id INT(11) DEFAULT NULL,    PRIMARY KEY(id)) ENGINE=InnoDB DEFAULT CHARSET=utf8;INSERT INTO channel (id, cname, parent_id) VALUES     (13, '首页', -1),    (14, 'TV580', -1),    (15, '生活580', -1),    (16, '左上幻灯片', 13),    (17, '帮忙', 14),    (18, '栏目简介', 17);

二、树形遍历实现:递归存储程序与路径拼接

为了实现树形遍历,我们需要一个递归存储程序来遍历树结构,并记录节点的路径。由于MySQL的UDF(用户定义函数)无法直接支持递归调用,我们需要借助存储程序来模拟递归功能。

1. 递归存储程序:获取节点路径

以下是用于拼接节点路径的递归存储程序:

DELIMITER //DROP PROCEDURE IF EXISTS pro_cre_pathlist;CREATE PROCEDURE pro_cre_pathlist(    IN nid INT,    IN delimit VARCHAR(10),    OUT pathstr VARCHAR(1000))BEGINDECLARE done INT DEFAULT 0;DECLARE parent_id INT DEFAULT 0;DECLARE cur1 CURSOR FOR    SELECT t.parent_id,            CONCAT(CAST(t.parent_id AS CHAR), delimit, pathstr)     FROM channel AS t    WHERE t.id = nid;-- 设置递归深度上限SET max_sp_recursion_depth = 12;OPEN cur1;FETCH cur1 INTO parent_id, pathstr;WHILE done = 0 DO    IF cur1 NOT FOUND        SET done = 1;    ELSE        -- 递归调用存储程序,继续拼接路径        CALL pro_cre_pathlist(parent_id, delimit, pathstr);        FETCH cur1 INTO parent_id, pathstr;    END IF;END WHILE;CLOSE cur1;END//DELIMITER ;

2. 递归存储程序解释

  • 游标cur1:用于遍历节点的父节点信息,拼接路径。
  • delimit参数:用于路径拼接时的分隔符,默认为斜杠/
  • 递归机制:通过设置max_sp_recursion_depth控制递归深度,防止栈溢出。
  • 路径拼接:使用CONCAT函数将当前节点的父节点ID与路径拼接,形成完整路径。

三、测试与验证

为了验证存储程序的正确性,我们可以执行以下SQL语句:

SET @str = '16';CALL pro_cre_pathlist(16, '/', @str);SELECT @str;

测试结果:假设存储程序正常运行,执行上述SQL语句后,@str的值会返回节点16的完整路径。


四、总结

通过上述方法,我们成功实现了MySQL树形数据的递归遍历。这种方法利用存储程序模拟了Oracle的SYS_CONNECT_BY_PATH功能,适用于需要深度树形遍历的场景。虽然需要手动设置递归深度上限,但这种方法在大多数实际应用中是可行且高效的。

如果需要更高效的解决方案,可以考虑使用MySQL的GROUP BYHAVING组合,或者第三方工具(如PHP)来实现递归遍历。

上一篇:mysql用于检索的关键字_Mysql全文搜索match...against的用法
下一篇:mysql状态查看 QPS/TPS/缓存命中率查看

发表评论

最新留言

感谢大佬
[***.8.128.20]2026年06月12日 13时04分15秒

关于作者

    喝酒易醉,品茶养心,人生如梦,品茶悟道,何以解忧?唯有杜康!
-- 愿君每日到此一游!

推荐文章