【MySQL疑难杂症】如何将树形结构存储在数据库中(方案三 Closure Table)

本文涉及的产品
RDS MySQL Serverless 基础系列,0.5-2RCU 50GB
云数据库 RDS MySQL,集群系列 2核4GB
推荐场景:
搭建个人博客
RDS MySQL Serverless 高可用系列,价值2615元额度,1个月
简介:   今天介绍将树形结构存储在数据库中的第三种方法——终结表(原谅我这生硬的翻译。。)。  继续用上一篇的栗子,下面是要存储的结构图:  需要回答的问题依旧是这样几个:  1.查询小天的直接上司。

  今天介绍将树形结构存储在数据库中的第三种方法——终结表(原谅我这生硬的翻译。。)。

  继续用上一篇的栗子,下面是要存储的结构图:

  需要回答的问题依旧是这样几个:

  1.查询小天的直接上司。

  2.查询老宋管理下的直属员工。

  3.查询小天的所有上司。

  4.查询老王管理的所有员工。

方案三、Closure Table 终结表法,保存每个节点与其各个子节点的关系,也就是记录以其为根节点的全部子节点信息。直接上代码就明白了:

  这里要创建两个表,一个表用来存储信息:

CREATE TABLE employees3(
eid INT,
ename VARCHAR(100),
position VARCHAR(100)
)

  一个表用来存储关系:

CREATE TABLE emp_relations(
root_id INT,
depth INT,
is_leaf TINYINT(1),
node_id INT
)

  这里的root_id用来存放以其为根节点的路径,node_id表示节点处的eid,depth表示根节点到该节点的深度,is_leaf表示该节点是否为叶子节点。

  接下来插入数据:

  可以看出,这个关系表有点大,我们先来看看查询效果如何:

  1.查询小天的直接上司。

  这里只需要在关系表中找到node_id为小天id,depth为1的根节点id即可。

SELECT e2.ename BOSS FROM employees3 e1,employees3 e2,emp_relations rel 
WHERE e1.ename='小天' AND rel.node_id=e1.eid AND rel.depth=1 AND e2.eid=rel.root_id

  查询结果如下:

  

  2.查询老宋管理下的直属员工。

  思路差不多,只要查询root_id为老宋eid且深度为1的node_id即为其直接下属员工id

SELECT e1.eid,e1.ename 直接下属 FROM employees3 e1,employees3 e2,emp_relations rel 
WHERE e2.ename='老宋' AND rel.root_id=e2.eid AND rel.depth=1 AND e1.eid=rel.node_id

  查询结果如下:

  

  3.查询小天的所有上司。

  只要在关系表中找到node_id为小天eid且depth大于0的root_id即可

SELECT e2.eid,e2.ename 上司 FROM employees3 e1,employees3 e2,emp_relations rel 
WHERE e1.ename='小天' AND rel.node_id=e1.eid AND rel.depth>0 AND e2.eid=rel.root_id

  查询结果如下:

  

  4.查询老王管理的所有员工。

  只要在关系表中查找root_id为老王eid,depth大于0的node_id即可

SELECT e1.eid,e1.ename 下属 FROM employees3 e1,employees3 e2,emp_relations rel 
WHERE e2.ename='老王' AND rel.root_id=e2.eid AND rel.depth>0 AND e1.eid=rel.node_id

  查询结果如下:

 

  我们可以发现,这四个查询的复杂程度是一样的,这就是这种存储方式的优点,而且可以让另一张表只存储跟节点紧密相关的信息,看起来更简洁。但缺点也显而易见,关系表会很庞大,当层次很深,结构很庞大的时候,关系表数据的增长会越来越快,相当于用空间效率来换取了查找上的时间效率。

  至此,树形结构在数据库中存储的三种方式就介绍完了,接下来对比一下三种方法:

  方案一:Adjacency List

  优点:只存储上级id,存储数据少,结构类似于单链表,在查询相邻节点的时候很方便。添加删除节点都比较简单。

  缺点:查询多级结构的时候会显得力不从心。

  适用场合:对多级查询需求不大的场景比较适用。

  方案二:Path Enumeration

  优点:查询多级结构的时候比较方便。查询相邻节点时也比较ok。增加或者删除节点的时候比较简单。

  缺点:需要存储的path值可能会很大,甚至超过设置的最大值范围,理论上无法无限扩张。

  适用场合:结构相对简单的场景比较适合。

  方案三:Closure Table

  优点:在查询树形结构的任意关系时都很方便。

  缺点:需要存储的数据量比较多,索引表需要的空间比较大,增加和删除节点相对麻烦。

  适用场合:纵向结构不是很深,增删操作不频繁的场景比较适用。

  当然,也可以再自己创新出其他更好的存储方案,如果有更好的想法,欢迎提出交流。

  至此三种方案全部介绍完毕,欢迎大家继续关注。

  我的博客即将同步至腾讯云+社区,邀请大家一同入驻。

真正重要的东西,用眼睛是看不见的。
相关实践学习
如何在云端创建MySQL数据库
开始实验后,系统会自动创建一台自建MySQL的 源数据库 ECS 实例和一台 目标数据库 RDS。
全面了解阿里云能为你做什么
阿里云在全球各地部署高效节能的绿色数据中心,利用清洁计算为万物互联的新世界提供源源不断的能源动力,目前开服的区域包括中国(华北、华东、华南、香港)、新加坡、美国(美东、美西)、欧洲、中东、澳大利亚、日本。目前阿里云的产品涵盖弹性计算、数据库、存储与CDN、分析与搜索、云通信、网络、管理与监控、应用服务、互联网中间件、移动服务、视频服务等。通过本课程,来了解阿里云能够为你的业务带来哪些帮助     相关的阿里云产品:云服务器ECS 云服务器 ECS(Elastic Compute Service)是一种弹性可伸缩的计算服务,助您降低 IT 成本,提升运维效率,使您更专注于核心业务创新。产品详情: https://www.aliyun.com/product/ecs
相关文章
|
22天前
|
缓存 关系型数据库 MySQL
高并发架构系列:数据库主从同步的 3 种方案
本文详解高并发场景下数据库主从同步的三种解决方案:数据主从同步、数据库半同步复制、数据库中间件同步和缓存记录写key同步,旨在帮助解决数据一致性问题。关注【mikechen的互联网架构】,10年+BAT架构经验倾囊相授。
高并发架构系列:数据库主从同步的 3 种方案
|
14天前
|
SQL 关系型数据库 MySQL
12 PHP配置数据库MySQL
路老师分享了PHP操作MySQL数据库的方法,包括安装并连接MySQL服务器、选择数据库、执行SQL语句(如插入、更新、删除和查询),以及将结果集返回到数组。通过具体示例代码,详细介绍了每一步的操作流程,帮助读者快速入门PHP与MySQL的交互。
29 1
|
16天前
|
SQL 关系型数据库 MySQL
go语言数据库中mysql驱动安装
【11月更文挑战第2天】
30 4
|
23天前
|
监控 关系型数据库 MySQL
数据库优化:MySQL索引策略与查询性能调优实战
【10月更文挑战第27天】本文深入探讨了MySQL的索引策略和查询性能调优技巧。通过介绍B-Tree索引、哈希索引和全文索引等不同类型,以及如何创建和维护索引,结合实战案例分析查询执行计划,帮助读者掌握提升查询性能的方法。定期优化索引和调整查询语句是提高数据库性能的关键。
118 1
|
11天前
|
运维 关系型数据库 MySQL
安装MySQL8数据库
本文介绍了MySQL的不同版本及其特点,并详细描述了如何通过Yum源安装MySQL 8.4社区版,包括配置Yum源、安装MySQL、启动服务、设置开机自启动、修改root用户密码以及设置远程登录等步骤。最后还提供了测试连接的方法。适用于初学者和运维人员。
106 0
|
24天前
|
监控 关系型数据库 MySQL
数据库优化:MySQL索引策略与查询性能调优实战
【10月更文挑战第26天】数据库作为现代应用系统的核心组件,其性能优化至关重要。本文主要探讨MySQL的索引策略与查询性能调优。通过合理创建索引(如B-Tree、复合索引)和优化查询语句(如使用EXPLAIN、优化分页查询),可以显著提升数据库的响应速度和稳定性。实践中还需定期审查慢查询日志,持续优化性能。
53 0
|
SQL Java 数据库连接
MySQL---数据库从入门走向大神系列(十五)-Apache的DBUtils框架使用
MySQL---数据库从入门走向大神系列(十五)-Apache的DBUtils框架使用
192 0
MySQL---数据库从入门走向大神系列(十五)-Apache的DBUtils框架使用
|
SQL 关系型数据库 MySQL
MySQL---数据库从入门走向大神系列(六)-事务处理与事务隔离(锁机制)
MySQL---数据库从入门走向大神系列(六)-事务处理与事务隔离(锁机制)
142 0
MySQL---数据库从入门走向大神系列(六)-事务处理与事务隔离(锁机制)
|
存储 SQL 关系型数据库
MySQL---数据库从入门走向大神系列(五)-存储过程
MySQL---数据库从入门走向大神系列(五)-存储过程
141 0
MySQL---数据库从入门走向大神系列(五)-存储过程
|
数据库
MySQL---数据库从入门走向大神系列(四)-子查询、表与表之间的关系(3)
MySQL---数据库从入门走向大神系列(四)-子查询、表与表之间的关系
203 0
MySQL---数据库从入门走向大神系列(四)-子查询、表与表之间的关系(3)
下一篇
无影云桌面