以下内容给大家介绍了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币余额
- 我的收藏
- 我的下载
- 下载帮助
最新资源
- 纸箱检测4-YOLO(v5至v9)、COCO、CreateML、Darknet、Paligemma、TFRecord数据集合集.rar
- 实习单位评估报告.pdf
- 节日装饰与活动策划:创造梦幻圣诞氛围全指南
- 纸箱检测23-YOLOv9数据集合集.rar
- 1键切换,随机播放本地音乐(适合管理大量本地音乐),无需联网,珍藏版音乐软件
- canoe的log数据文件读取
- 纸检测55-YOLOv5数据集合集.rar
- 实现vue+docxtemplater导出word文档功能时,需要引入的资源文件
- 个人PPT模板,总结或者作为素材使用
- 纸板、面料、纸类、塑料检测68-YOLO(v5至v9)、COCO、CreateML、Darknet、Paligemma、TFRecord、VOC数据集合集.rar