mysql 递归查询 (MySQL 8.0 ETC 递归查询)

博客主要围绕MySQL数据库展开,给出了数据库中`areas`表的创建代码及数据插入代码,还展示了表结构示意图。同时详细介绍了递归查询,包括从上向下和从下向上两种查询方式,给出了相应代码及注意的关系。

一、数据库数据

 

1、代码

-- ----------------------------
-- Table structure for areas
-- ----------------------------
DROP TABLE IF EXISTS `areas`;
CREATE TABLE `areas` (
  `id` int NOT NULL AUTO_INCREMENT,
  `name` varchar(255) NOT NULL COMMENT '行政区名称',
  `pid` int NOT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=23 DEFAULT CHARSET=utf8;

-- ----------------------------
-- Records of areas
-- ----------------------------
INSERT INTO `areas` VALUES ('1', '中国', '0');
INSERT INTO `areas` VALUES ('2', '北京市', '1');
INSERT INTO `areas` VALUES ('7', '东城区', '2');
INSERT INTO `areas` VALUES ('8', '西城区', '2');
INSERT INTO `areas` VALUES ('9', '朝阳区', '2');
INSERT INTO `areas` VALUES ('10', '丰台区', '2');
INSERT INTO `areas` VALUES ('11', '石景山区', '2');
INSERT INTO `areas` VALUES ('12', '海淀区', '2');
INSERT INTO `areas` VALUES ('13', '顺义区', '2');
INSERT INTO `areas` VALUES ('14', '通州区', '2');
INSERT INTO `areas` VALUES ('15', '大兴区', '2');
INSERT INTO `areas` VALUES ('16', '房山区', '2');
INSERT INTO `areas` VALUES ('17', '门头沟区', '2');
INSERT INTO `areas` VALUES ('18', '昌平区', '2');
INSERT INTO `areas` VALUES ('19', '平谷区', '2');
INSERT INTO `areas` VALUES ('20', '密云区', '2');
INSERT INTO `areas` VALUES ('21', '怀柔区', '2');
INSERT INTO `areas` VALUES ('22', '延庆区', '2');

 

2、示意图

 

二、递归查询

 

1、上向下查询

1)代码

with recursive cte as
(
select * from areas where id = 1
union all
select c.* from areas c, cte where c.pid = cte.id
)
select * from cte order by pid, id asc

其中cte为生成结果的临时表名称(该名称可以为任意名称)

areas为查询表名称

注意关系:c.pid = cte.id

 

2)结果

 

2、由下向上

1)代码

with recursive cte as
(
select * from areas where id = 12
union all
select c.* from areas c, cte where c.id = cte.pid
)
select * from cte order by pid, id asc

其中cte为生成结果的临时表名称(该名称可以为任意名称)

areas为查询表名称

注意关系:c.id = cte.pid

 

2)结果

 

 

 

MySQL 5.7 和 MySQL 8.0 是 Oracle 公司发布的两个重要版本,MySQL 8.0 在性能、安全性、功能和开发体验上对 5.7 做了大量改进。以下是它们之间的主要区别: --- ### ✅ 1. **默认字符集和排序规则变化** - **MySQL 5.7**: - 默认字符集:`latin1` - 默认排序规则:`latin1_swedish_ci` - **MySQL 8.0**: - 默认字符集:`utf8mb4` - 默认排序规则:`utf8mb4_0900_ai_ci` > `utf8mb4` 支持完整的 UTF-8 编码(包括 emoji),更符合现代 Web 应用需求。 ```sql -- 查看当前默认字符集 SHOW VARIABLES LIKE 'character_set_server'; SHOW VARIABLES LIKE 'collation_server'; ``` --- ### ✅ 2. **窗口函数(Window Functions)支持** MySQL 8.0 引入了标准 SQL 的窗口函数,极大增强了分析型查询能力。 ```sql -- 示例:使用 ROW_NUMBER() 给成绩排名 SELECT name, score, ROW_NUMBER() OVER (ORDER BY score DESC) AS rank_num FROM students; ``` > 这在 5.7 中无法直接实现,需用变量或子查询模拟,复杂且易错。 --- ### ✅ 3. **通用达式(CTE)支持** MySQL 8.0 支持递归和非递归 CTE(Common Table Expressions),使复杂查询更清晰。 ```sql -- 非递归 CTE WITH top_students AS ( SELECT name, score FROM students WHERE score > 90 ) SELECT * FROM top_students; -- 递归 CTE:生成数字序列 WITH RECURSIVE nums AS ( SELECT 1 AS n UNION ALL SELECT n + 1 FROM nums WHERE n < 5 ) SELECT * FROM nums; ``` > 5.7 不支持 `WITH` 语句。 --- ### ✅ 4. **JSON 支持增强** MySQL 8.0 提供了更强的 JSON 功能,包括: - **JSON 达式索引** - **内联路径操作符 -> 和 ->>** - **JSON 合并、移除、修改函数** ```sql -- 使用 -> 简化 JSON 提取 SELECT data->'$.name' AS name, data->>'$.name' AS name_plain FROM users; -- 创建 JSON 列上的虚拟列并加索引 ALTER TABLE users ADD name VARCHAR(50) AS (data->>'$.name'); CREATE INDEX idx_name ON users(name); ``` > 5.7 虽支持 JSON 类型,但无达式索引和便捷操作符。 --- ### ✅ 5. **性能优化器改进** MySQL 8.0 重写了优化器,支持: - 成本模型(Cost Model)优化 - 直方图统计(Histogram Statistics)提升执行计划准确性 - 更智能的连接顺序选择 ```sql -- 创建直方图 ANALYZE TABLE employees UPDATE HISTOGRAM ON salary; ``` --- ### ✅ 6. **原子 DDL 操作(Atomic DDL)** MySQL 8.0 实现了 **原子性 DDL**:如 `CREATE`, `DROP`, `ALTER` 要么全部成功,要么回滚,保证数据字典一致性。 > 5.7 中 DDL 可能导致部分完成状态。 --- ### ✅ 7. **数据字典重构** - MySQL 8.0 使用 **事务性数据字典**(基于 InnoDB 存储),取代原来的 `.frm` 文件。 - 所有元数据统一管理,更加安全可靠。 > 5.7 使用文件系统存储结构信息(`.frm`, `.par`, etc),容易损坏。 --- ### ✅ 8. **安全性和权限系统增强** - **角色(Roles)支持**:可以创建角色并分配给用户,简化权限管理。 ```sql CREATE ROLE 'app_developer', 'read_only'; GRANT ALL ON mydb.* TO 'app_developer'; GRANT 'app_developer' TO 'alice@localhost'; SET DEFAULT ROLE 'app_developer' TO 'alice@localhost'; ``` - 密码策略增强(如历史密码限制、失败登录锁定等) --- ### ✅ 9. **InnoDB 改进** - **InnoDB 默认为全局事务 ID(GTID)复制做好准备** - **隐藏主键自增优化** - **Lob 索引页外存储优化** - **死锁检测默认开启(innodb_deadlock_detect = ON)** --- ### ✅ 10. **性能模式(Performance Schema)增强** - 更多监控项(如内存使用、线程状态) - 支持 `setup_consumers` 动态配置 - 提供 `sys schema` 更好地分析性能问题 ```sql -- 查看最慢的语句 SELECT * FROM sys.statement_analysis ORDER BY avg_latency DESC LIMIT 5; ``` --- ### ✅ 11. **降序索引(Descending Indexes)** MySQL 8.0 支持真正的降序索引(之前只是语法忽略): ```sql CREATE INDEX idx_score_desc ON students (score DESC, subject ASC); ``` > 在 5.7 中 `DESC` 被忽略,实际仍是升序。 --- ### ✅ 12. **备份锁(Backup Locks)** 新增轻量级锁机制,用于在线备份时不阻塞 DML: ```sql LOCK INSTANCE FOR BACKUP; -- 执行拷贝 ... UNLOCK INSTANCE; ``` --- ### ✅ 13. **默认身份验证插件变更** - MySQL 8.0 默认使用 `caching_sha2_password` - 5.7 使用 `mysql_native_password` > 注意:旧客户端(如 PHP < 7.4, Python mysqlclient)可能无法连接 8.0,需调整配置: ```ini # my.cnf default_authentication_plugin=mysql_native_password ``` --- ### ✅ 升级注意事项 | 项目 | 建议 | |------|------| | 字符集兼容 | 检查现有数据是否适合 `utf8mb4` | | 认证插件 | 若应用不支持 `caching_sha2_password`,需改回 | | SQL 模式 | 8.0 默认启用了严格模式 | | 备份恢复 | 使用 `mysqldump` 或 `mysqlbackup` 工具升级 | --- ### 总结对比 | 特性 | MySQL 5.7 | MySQL 8.0 | |------|----------|----------| | 默认字符集 | latin1 | utf8mb4 | | 窗口函数 | ❌ | ✅ | | CTE(递归) | ❌ | ✅ | | JSON 达式索引 | ❌ | ✅ | | 原子 DDL | ❌ | ✅ | | 角色支持 | ❌ | ✅ | | 降序索引 | 伪支持 | 真正支持 | | 数据字典 | 文件基础 | 事务性 Innodb 存储 | | 默认认证插件 | mysql_native_password | caching_sha2_password | | 性能模式增强 | 一般 | 强大(含 sys schema) | --- ### 推荐使用场景 - **新项目**:强烈推荐使用 **MySQL 8.0** - **老系统维护**:可继续使用 5.7,但建议规划升级 - **高并发分析型查询**:8.0 的窗口函数和 CTE 极大提升开发效率 ---
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值