从 MySQL 5.7 到 8.0:理解 GROUP BY 的新规则与实战优化20241112

🎯 从 MySQL 5.7 到 8.0:理解 GROUP BY 的新规则与实战优化

🔎 引言

随着 MySQL 的不断升级,从 5.7 到 8.0,不仅性能得到提升,其对 SQL 标准的严格执行也显著提高。GROUP BY 的行为变化就是一个典型例子。对开发者而言,MySQL 8.0 强制遵守 ONLY_FULL_GROUP_BY 规则,虽然提高了数据一致性,但也为老代码迁移带来了不小的挑战。

本文将从 问题背景 出发,通过 报错分析 和 案例复盘,探讨如何应对 MySQL 升级带来的挑战,同时总结出一套高效的解决方案。

🌟 一、问题背景:MySQL 升级带来的挑战

1. 什么是 GROUP BY?

GROUP BY 是一种将数据按字段分组的 SQL 操作,通常用于统计、聚合和分析场景。示例如下:

SELECT department, COUNT(*) AS employee_count
FROM employees
GROUP BY department;

2. MySQL 5.7 的行为

  • 默认启用了 ONLY_FULL_GROUP_BY 模式,但执行较为宽松。
  • 某些情况下,未完全符合规则的查询也能隐式运行。

3. MySQL 8.0 的行为

  • 严格执行 ONLY_FULL_GROUP_BY 模式。
  • 未分组字段或未使用聚合函数的字段会直接报错。
  • 示例:
SELECT column1, column2, MAX(column3)
FROM table_name
GROUP BY column1;

在 MySQL 8.0 中,若 column2 未出现在 GROUP BY 或未使用聚合函数,将报错:

Expression #2 of SELECT list is not in GROUP BY clause and contains nonaggregated column 'column2' which is not functionally dependent on columns in GROUP BY clause.

🚨 二、常见报错与原因

1. 报错示例 1

SELECT column1, column2
FROM table_name
GROUP BY column1;
  • 错误信息:
Expression #2 of SELECT list is not in GROUP BY clause and contains nonaggregated column 'column2'.

原因:column2 既未分组也未聚合,违反了 SQL 标准。

2. 报错示例 2

SELECT column1, MAX(column2), column3
FROM table_name
GROUP BY column1;
  • 错误信息:
Expression #3 of SELECT list is not in GROUP BY clause and contains nonaggregated column 'column3'.

原因:column3 未分组或聚合,与 ONLY_FULL_GROUP_BY 规则冲突。

🔧 三、解决方案

方法 1:修改 SQL 查询 🛠️

调整查询以符合 GROUP BY 规则:
1. 所有未聚合字段必须出现在 GROUP BY 中。
2. 为未分组字段使用聚合函数。

示例改写:

-- 错误写法
SELECT column1, column2
FROM table_name
GROUP BY column1;-- 正确写法
SELECT column1, MAX(column2) AS max_column2
FROM table_name
GROUP BY column1;
  • 优缺点:
    • ✅ 优点:符合标准,解决问题的长远之道。
    • ❌ 缺点:需要对旧代码进行大规模修改。

方法 2:调整 MySQL 配置 ⚙️

通过调整 MySQL 的 sql_mode 配置,禁用 ONLY_FULL_GROUP_BY:

步骤:

1. 检查当前 sql_mode:
SELECT @@GLOBAL.sql_mode;

输出示例:

STRICT_TRANS_TABLES,ONLY_FULL_GROUP_BY,NO_ENGINE_SUBSTITUTION
2. 移除 ONLY_FULL_GROUP_BY:
SET GLOBAL sql_mode=(SELECT REPLACE(@@sql_mode, 'ONLY_FULL_GROUP_BY', ''));
3. 修改配置文件,永久禁用:编辑 /etc/mysql/my.cnf:
[mysqld]
sql_mode=STRICT_TRANS_TABLES,ERROR_FOR_DIVISION_BY_ZERO,NO_ENGINE_SUBSTITUTION
4. 重启 MySQL 服务:
sudo systemctl restart mysql

验证:

SELECT @@GLOBAL.sql_mode;

输出中不应包含 ONLY_FULL_GROUP_BY。

优缺点:
• ✅ 优点:快速解决问题,无需修改 SQL。
• ❌ 缺点:可能导致聚合结果错误,需谨慎使用。

🔍 四、插曲:配置文件冲突与排查

1. 配置文件加载顺序

MySQL 加载配置文件的顺序如下:
1. /etc/my.cnf
2. /etc/mysql/my.cnf
3. /etc/mysql/conf.d/.cnf
4. /etc/mysql/mysql.conf.d/
.cnf

  • 问题:
    多个配置文件中定义了 sql_mode,后加载的文件会覆盖前面的设置。

2. 如何发现冲突?

  • 检查所有配置文件:
sudo grep -R "sql_mode" /etc/mysql/
  • 查看实际加载的配置文件:
mysql --help | grep "Default options"
  • 验证实际生效的 sql_mode:
SELECT @@GLOBAL.sql_mode;

3. 解决冲突的最佳实践

•	将主要的 sql_mode 定义放在 /etc/mysql/my.cnf。
•	针对工具(如 mysqldump)的特殊需求,单独在 /etc/mysql/conf.d/*.cnf 中配置。

📚 五、实际案例复盘

案例 1:查询菜单类型统计

表名:eb_system_menu
表结构:

+------------+--------------+
| Field      | Type         |
+------------+--------------+
| id         | int          |
| menu_type  | varchar(2)   |
| name       | varchar(100) |
+------------+--------------+

需求:统计每种菜单类型的数量。

SELECT menu_type, COUNT(*) AS count
FROM `ydkj-mall`.`eb_system_menu`
GROUP BY menu_type;

案例 2:用户状态分布统计

表名:eb_user
表结构:

+------------+--------------+
| Field      | Type         |
+------------+--------------+
| uid        | int          |
| status     | tinyint(1)   |
| nickname   | varchar(100) |
+------------+--------------+

需求:统计每种状态的用户数量。

SELECT status, COUNT(*) AS user_count
FROM `ydkj-mall`.`eb_user`
GROUP BY status;

🎯 六、总结与最佳实践

1. 理解 MySQL 的变化

MySQL 8.0 的严格模式符合标准化要求,虽然迁移成本较高,但能显著提高数据一致性。

2. 合理选择解决方案

  • 修改 SQL 查询是最推荐的长远方案。
  • 调整 sql_mode 可作为短期过渡,但需严格测试。

3. 配置管理的建议

  • 集中管理 sql_mode,避免多文件冲突。
  • 使用工具检查实际生效的配置,确保一致性。

🎉 附录:常用 SQL 验证命令

-- 查看当前模式
SELECT @@GLOBAL.sql_mode;-- 查看表结构
DESCRIBE `table_name`;-- 显示加载的配置文件
mysql --help | grep "Default options";

通过对 MySQL 的深入分析和实战操作,相信你已经掌握了解决 GROUP BY 规则冲突的技巧。希望这篇文章能帮助你在数据库升级中游刃有余,轻松应对变化! 😊

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/web/59388.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【activiti工作流源码集成】springboot+activiti+mysql+vue+redis工作流审批流集成整合业务绑定表单流程图会签驳回

工作流集成实际项目案例,demo提供 源码获取方式:本文末个人名片直接获取。 前言 activiti工作流引擎项目,企业erp、oa、hr、crm等企事业办公系统轻松落地,请假审批demo从流程绘制到审批结束实例。 一、项目形式 springbootvue…

如何判断FPGA能够接入几个Camera

摘要:仅记录判断FPGA能够接入几个Camera的思路 在FPGA中,"quad"和"bank"是两个不同的概念,它们通常用于描述FPGA中的高速串行收发器(如Xilinx的GTX或GTH收发器)的组织方式。 Quad: 一个Quad包含…

CKA认证 | Day2 K8s内部监控与日志

第三章 Kubernetes监控与日志 1、查看集群资源状态 在 Kubernetes 集群中,查看集群资源状态和组件状态是非常重要的操作。以下是一些常用的命令和解释,帮助你更好地管理和监控 Kubernetes 集群。 1.1 查看master组件状态 Kubernetes 的 Master 组件包…

推荐一款好用的postman替代工具2024

Apifox 是国内团队自主研发的 API 文档、API 调试、API Mock、API 自动化测试一体化协作平台,是非常好的一款 postman 替代工具。 它通过一套系统、一份数据,解决多个系统之间的数据同步问题。只要定义好接口文档,接口调试、数据 Mock、接口…

《自动化运维》

一、引言 在当今信息技术飞速发展的时代,企业的 IT 系统规模不断扩大,复杂性日益增加。传统的手工运维方式已经无法满足高效、稳定、可靠的运维需求。自动化运维作为一种先进的运维理念和技术手段,正逐渐成为企业提升 IT 运维效率和质量的关键…

相机光学(四十二)——sony的HDR技术

1.概述 索尼的HDR技术包括以下几种,这些技术共同构成了索尼在HDR领域的技术矩阵,旨在提供更宽广的动态范围、更丰富的色彩表现以及更真实的光影效果: Multi-frame HDR(多帧异曝光HDR):这是一种通过不同曝光时间图像的多帧合成来实…

Springboot环境搭建详解

springboot学习视频记录: 笔记: a:Springboot maven常见依赖、配置文件笔记-CSDN博客 b:Springboot环境搭建详解-CSDN博客 day01 6:springboot的parent和starter依赖- a 7:启动类的位置配置- b 8&am…

uniapp+vue2 设置全局变量和全局方法 (兼容h5/微信小程序)

一,Vue.prototype.xxx 问题:js可以使用,但是微信小程序,在template 模板无法使用 二,globalData 问题同上,优点就是,.js文件也可以使用。但是微信小程序,在template 模板无法使用…

gdb调试redis。sudo

1.先启动redis-server和一个redis-cli。 2.ps -aux|grep reids查看redis相关进程。 3.开始以管理员模式附加进程调试sudo gdb -p 2968.注意这里不能不加sudo,因为Redis 可能以 root 用户启动,普通用户无法附加到该进程。否则就会出现可能下列情形&#…

uniapp 设置安全区域

<!-- 获取安全区域 --> <script setup lang"ts"> import { computed, ref } from vuelet systemType ref(1) // #ifdef APP-PLUS || H5 || APP-PLUS-NVUE systemType.value 1 const { safeAreaInsets } uni.getSystemInfoSync() console.log(safeAre…

YUM 的使用

YUM 是一个用于 Fedora 和 Red Hat 以及 CentOS 操作系统的前端软件包管理器&#xff0c;它可以自动处理依赖关系并一次性安装所有必需的软件包。 镜像站点选择 1. 备份原有的镜像源配置文件 系统默认的 yum 镜像源配置文件存储在 /etc/yum.repos.d/ 目录下&#xff0c;可以…

力扣 LeetCode 242. 有效的字母异位词(Day3:哈希表)

解题思路&#xff1a; 哈希表三种数据结构的选择 1. 数组&#xff1a;适用于数据量小的情况 2. set&#xff1a;适用于数据量大的情况 3. map&#xff1a;适用于key-value 什么时候用哈希表&#xff1f; 给你一个元素&#xff0c;判断该元素在这个集合里是否出现过 本题使…

【MYSQL】锁详解(全局锁、表级锁、行级锁)【快速理解】

目录 一、全局锁 二、表级锁 1.表锁 2.元数据锁 3.意向锁 三、行级锁 1. 行锁 2.间隙锁 3.临建锁 锁是处理并发情况下&#xff0c;对数据的一致性的关键因素&#xff0c;也是并发情况下对效率影响非常大的。 1、全局锁&#xff1a;锁定表中所有数据。 2、表级锁&#xff1a;…

蓝桥杯每日真题 - 第11天

题目&#xff1a;&#xff08;合并数列&#xff09; 题目描述&#xff08;14届 C&C B组D题&#xff09; 解题思路&#xff1a; 题意理解&#xff1a;给定两个数组&#xff0c;目标是通过若干次合并操作使两个数组相同。每次合并操作可以将数组中相邻的两个数相加&#xff…

Anaconda 和 conda 是什么关系?就像 pip 和 python 一样吗

Anaconda 和 conda是 Anaconda Distribution 还是 Miniconda Anaconda 和 conda Anaconda 和 conda 之间的关系有点类似于 pip 和 Python&#xff0c;但又有所不同。 Anaconda 是一个数据科学和机器学习的发行版&#xff0c;它包含了 Python、conda 以及许多预装的库和工具&am…

contos7.9 部署3节点 hadoop3.4 集群 非高可用

contos7.9 部署3节点 hadoop3.4 集群 非高可用 contos7.9 部署3节点 hadoop3.4 集群 非高可用环境信息服务器角色分配服务器配置服务器配置初始化 init_server.sh配置主机名映射所有节点配置 hosts文件 配置免密登录 hadoop 安装环境配置下载安装包下载 jdk1.8hadoop3.4 分发安…

linux之时间服务器

序 在项目开发中,各个模块的时间同步是一个重要的机制;那么如何在linux上搭建时间服务器呢?并且客户端怎么与服务器进行时间同步呢? 时间服务器搭建 linux中有两种时间服务器: ntp服务器和chrony服务器 1.ntp服务器 1.1 安装 apt install ntp 1.2 配置 配置文件一般在…

人工智能:重塑医疗、企业与生活的未来知识管理——以HelpLook为例

一、医疗行业&#xff1a;AI引领的医疗革新 随着人工智能&#xff08;AI&#xff09;技术的持续飞跃&#xff0c;我们正身处一场跨行业的深刻变革之中。在医疗健康的广阔舞台上&#xff0c;人工智能技术正扮演着日益重要的角色。它不仅能够辅助医生进行病例的精准诊断&#xf…

arcgis做buffer

用csv存好地址&#xff0c;xy加入arcgis&#xff0c;选择投影用Geographic - WGS 1984&#xff0c;否则不会显示在地图上 然后把投影改成Hong Kong 1980 Grid&#xff0c;命名为address_grid 一开始做buffer的时候没有反应&#xff0c;选择5m没有反应&#xff0c;选择decimal…

Aippyy如何写论文?ai人工智能写作哪家好?

Aippyy是一个智能论文写作工具&#xff0c;它可以帮助用户生成论文大纲和正文。以下是使用Aippyy写论文的一般步骤&#xff1a; 首先是生成论文大纲&#xff0c;一篇好的论文一定是有清晰的论文大纲作为支撑的&#xff0c;有了框架才能更好的寻找思路、填充内容。只需要输入我…