以下内容给大家介绍了MYSQL通过Adjacency List (邻接表)来存储树形结构的过程介绍和解决办法,并把存储后的图例做了分析。 今天来看看一个比较头疼的问题,如何在数据库中存储树形结构呢? 像mysql这样的关系型数据库,比较适合存储一些类似表格的扁平化数据,但是遇到像树形结构这样有深度的人,就很难驾驭了。 举个栗子:现在有一个要存储一下公司的人员结构,大致层次结构如下: (画个图真不容易。。) 那么怎么存储这个结构?并且要获取以下信息: 1.查询小天的直接上司。 2.查询老宋管理下的直属员工。 3.查询小天的所有上司。 4.查询老王管理的所有员工。 方案一、(Adjacenc 在MySQL中,存储树形结构的数据模式之一是 Adjacency List(邻接表)模型。这种方法主要是通过在每个节点(在本例中是员工)中存储其直接上级的ID来实现的。下面我们将深入探讨如何使用邻接表来存储公司人员结构,并解决与之相关的查询问题。 创建一个名为`Employees`的表,它包含以下字段: 1. `eid`: 员工ID,整数类型,用于唯一标识每个员工。 2. `ename`: 员工姓名,VARCHAR类型,用于存储员工的名字。 3. `position`: 职位,VARCHAR类型,表示员工的职位。 4. `parent_id`: 父ID,整数类型,表示该员工的直接上级的ID。 例如,按照上述公司人员结构,我们可以插入如下数据: ```sql INSERT INTO Employees (eid, ename, position, parent_id) VALUES (1, '老王', 'CEO', NULL), (2, '老宋', '部门经理', 1), (3, '小天', '工程师', 2); ``` 接着,我们来解决四个查询问题: 1. 查询小天的直接上司: ```sql SELECT e2.eid, e2.ename FROM Employees e1, Employees e2 WHERE e1.parent_id = e2.eid AND e1.ename = '小天'; ``` 这个查询会返回小天的直接上级的ID和姓名,即老宋。 2. 查询老宋管理下的直属员工: ```sql SELECT e1.eid, e1.ename FROM Employees e1, Employees e2 WHERE e1.parent_id = e2.eid AND e2.ename = '老宋'; ``` 这个查询会返回所有直接隶属于老宋的员工ID和姓名。 3. 查询小天的所有上司(包括间接上司): 这个问题需要使用存储过程来解决,因为邻接表模型无法直接通过单个SQL查询得到所有上司。创建如下的存储过程: ```sql DELIMITER // CREATE PROCEDURE getSuperiors(IN uid INT, OUT superiors VARCHAR(1000)) BEGIN DECLARE sTemp INTEGER DEFAULT uid; DECLARE tmpName VARCHAR(20); SET superiors = ''; WHILE (sTemp > 0) DO SELECT parent_id INTO sTemp FROM Employees WHERE eid = sTemp; SELECT ename INTO tmpName FROM Employees WHERE eid = sTemp; SET superiors = CONCAT(tmpName, ',', superiors); END WHILE; SET superiors = LEFT(superiors, CHAR_LENGTH(superiors) - 1); END // DELIMITER ; ``` 然后调用存储过程: ```sql CALL getSuperiors(3, @result); SELECT @result; ``` 结果将返回小天的所有上司姓名,按层级顺序排列。 4. 查询老王管理的所有员工: 使用递归查询或存储过程来获取所有下属。这里展示一种使用存储过程的方法: ```sql DELIMITER // CREATE PROCEDURE getSubordinate(IN uid INT, OUT result VARCHAR(2000)) BEGIN DECLARE str VARCHAR(1000); DECLARE cid VARCHAR(100); DECLARE tmpName VARCHAR(100); SET str = '$'; SET cid = CAST(uid AS CHAR(10)); WHILE cid IS NOT NULL DO SET str = CONCAT(str, ',', cid); SELECT GROUP_CONCAT(eid) INTO cid FROM Employees WHERE FIND_IN_SET(parent_id, cid); END WHILE; SELECT GROUP_CONCAT(ename) INTO result FROM Employees WHERE FIND_IN_SET(eid, str); END // DELIMITER ; ``` 调用存储过程获取结果: ```sql CALL getSubordinate(1, @result); SELECT @result; ``` 这将返回所有属于老王管理的员工姓名。 总结,邻接表模型在MySQL中是一种常见的存储树形结构的方式,尽管它对于获取所有上级或下级关系可能需要复杂的查询和存储过程。然而,这种模型对于简单的查询(如直接上级)和数据插入更新较为高效。在实际应用中,根据具体需求和数据规模,可能需要权衡使用其他如Nested Sets Model或Path Enumeration Model等方法。
- 粉丝: 3
- 资源: 917
- 我的内容管理 展开
- 我的资源 快来上传第一个资源
- 我的收益 登录查看自己的收益
- 我的积分 登录查看自己的积分
- 我的C币 登录后查看C币余额
- 我的收藏
- 我的下载
- 下载帮助
最新资源
- 基于SpringBoot+Vue的校园招聘管理系统(前端代码)
- C++期末大作业-2024-QT仓库商品管理系统,经过老师审定过的,应该能够满足学习、使用需求,如果有需要的话可以放心下载使用
- DH-GSTN5600 剩余电流式电气火灾监控探测器 安装使用说明书
- 天津理工大学信息系统设计实验
- jsp ssm 学校录取查询系统 高校志愿填报录取 项目源码 web java【项目源码+数据库脚本+项目说明+软件工具】毕设
- jsp ssm 网上购物系统 在线购物 在线商城平台 项目源码 web java【项目源码+数据库脚本+项目说明+软件工具】毕设
- 29网课交单平台源码最新修复全开源版本
- jsp ssm 超市网上购物系统 超市管理 超市购物 项目源码 web java【项目源码+数据库脚本+项目说明+软件工具】毕
- 海湾火灾自动报警系统主要设备参数
- C++自制多功能游戏头文件