后端与系统架构2610 字

MySQL8新特性优化父子层级关系数据CTE查询

·全库 374 / 611

《MySQL8新特性优化父子层级关系数据CTE查询》共 0.3 万字,通篇围绕 数据库、权限、场景、数据集 展开,归在「后端与系统架构」这一层。

覆盖数据库权限场景数据集MySQL微调

适合给 AI 系统搭底座、要管得住的人

目录骨架(6 节)
  1. CTE实战示例
  2. 扩展阅读
  3. CTE基本概念
  4. 语法介绍
  5. 递归语法结构
  6. 父子结构示例数据

引言

父子结构数据模型,又称为层次结构数据模型或树形结构,是一种在数据库中表示元素间具有上下级关系的数据组织方式。这种模型广泛应用于多种实际场景

主要包括但不限于:

​

组织架构管理:企业或机构内部的部门与员工关系,其中部门可以包含子部门,形成一个多层级的管理体系。

商品分类:电商平台的商品按照类别和子类别分层,如电子产品下有手机、电脑等子类,手机下又有不同品牌和型号。

文件系统目录:计算机文件系统的目录结构,文件夹可以包含子文件夹,形成树状结构。

内容管理系统:博客、论坛的帖子和评论,或是文章与其所属的多个标签之间的关联。

权限与角色管理:用户权限模型中,角色可以继承上级角色的权限,形成权限层次。

CTE基本概念

CTE,即Common Table Expression,是MySQL 8.0版本及以后引入的一个功能,是在SQL查询中定义的一种临时结果集,并给这个结果集命名,CTE通过WITH关键字引入,可以在SELECT、INSERT、UPDATE、DELETE语句之前定义并可以在同一查询中被多次引用。

CTE不是物理存储的对象,而是在查询执行期间临时存在的逻辑视图。CTE分为递归和非递归两种,其中递归CTE特别适用于处理上述父子结构数据,能够简便地实现树形结构的遍历查询。

​

语法介绍

非递归语法结构

WITH cte_name AS (
    SELECT column1, column2, ...
    FROM table_name
    WHERE condition
)

递归语法结构

递归CTE的基本语法结构包括两个部分:初始化查询(非递归部分)和递归成员(递归部分)。

WITH RECURSIVE cte_name AS (
    -- 初始化查询(非递归部分)
    SELECT column1, column2, ...
    FROM table_name
    WHERE condition_for_initial_rows
    
    UNION ALL
    
    -- 递归查询(递归部分)
    SELECT column1, column2, ...
    FROM cte_name
    JOIN another_table ON cte_name.some_column = another_table.related_column
    WHERE recursive_condition
)

在这个结构中,首先定义一个初始化查询来确定递归的起始点,然后通过UNION ALL连接递归查询部分,递归查询部分会引用自身的cte_name来扩展结果集,直到满足停止递归的条件。递归查询必须有一个明确的终止条件,否则会导致无限循环。

​

定义完CTE后,你就可以在紧接着的主要查询中像使用普通表那样使用这个cte_name。

SELECT ...
FROM cte_name
JOIN another_table ...
WHERE more_conditions;

父子结构示例数据

在数据库设计中,设计用于存储父子结构(也称为树形结构)的表时,最常见的方法是使用自引用关系,即在表中包含一个指向其父节点的外键。下面是一个简单的表设计示例:

CREATE TABLE `sys_company` (
  `dept_id` bigint NOT NULL COMMENT '部门id',
  `parent_id` bigint DEFAULT '0' COMMENT '父部门id',
  `dept_name` varchar(30) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT '' COMMENT '部门名称',
  PRIMARY KEY (`dept_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci COMMENT='部门表';

表示例数据

INSERT INTO `sys_company`(`dept_id`, `parent_id`, `dept_name`) VALUES (100, 0, '沫离科技-广东省');
INSERT INTO `sys_company`(`dept_id`, `parent_id`, `dept_name`) VALUES (101, 100, '深圳总公司');
INSERT INTO `sys_company`(`dept_id`, `parent_id`, `dept_name`) VALUES (102, 100, '广州总公司');
INSERT INTO `sys_company`(`dept_id`, `parent_id`, `dept_name`) VALUES (103, 0, '沫离科技-江西省');
INSERT INTO `sys_company`(`dept_id`, `parent_id`, `dept_name`) VALUES (104, 103, '赣州总公司');
INSERT INTO `sys_company`(`dept_id`, `parent_id`, `dept_name`) VALUES (105, 101, '福田区分公司');
INSERT INTO `sys_company`(`dept_id`, `parent_id`, `dept_name`) VALUES (106, 101, '南山区分公司');
INSERT INTO `sys_company`(`dept_id`, `parent_id`, `dept_name`) VALUES (107, 103, '南昌总公司');
INSERT INTO `sys_company`(`dept_id`, `parent_id`, `dept_name`) VALUES (108, 103, '九江总公司');
INSERT INTO `sys_company`(`dept_id`, `parent_id`, `dept_name`) VALUES (109, 104, '章贡区分公司');

资料里没有你的场景?

把你手上的数据和想解决的那个环节发上来,我们按具体情况回,不复述方法论。

发布需求