MySQL 5.7与8.0怎么选?新旧版本差异及兼容性分析
如果只是比较 MySQL 5.7 和 8.0 的功能与技术能力,8.0 明显更适合作为升级方向:它增加了窗口函数、CTE、角色管理、新数据字典、原子 DDL 等能力,同时改进了字符集、安全认证和优化器。不过,版本选择还要考虑一个容易被忽略的问题:截至 2026 年,MySQL 5.7 和 MySQL 8.0 都已经不是适合新项目长期使用的目标版本。
MySQL 5.7.44 是 5.7 系列的最终版本,发布于 2023 年 10 月 25 日;MySQL 官方从这一天起将 5.7 纳入 Sustaining Support。MySQL 8.0 的最终版本为 8.0.46,官方发布说明同时指出该系列于 2026 年 4 月进入 EOL。因此,如果现在新建生产环境,更合理的做法通常是直接评估当前受支持的 LTS 系列,例如 MySQL 8.4,而不是在 5.7 和 8.0 中选择一个重新开始部署。
但对于仍然运行 MySQL 5.7 的旧项目,“5.7 还是 8.0”仍然是一个现实问题,因为从 5.7 迁移到更新版本时,8.0 往往处在兼容性改造和升级路径的中间位置。下面就从实际使用和迁移角度分析。
一、如果只看5.7和8.0,两者到底差在哪里
MySQL 8.0 并不是简单地在 5.7 基础上增加几个参数。它在 SQL 能力、内部元数据管理、认证方式、字符集默认值和优化器功能等方面都有明显变化。
| 比较项目 | MySQL 5.7 | MySQL 8.0 | 实际影响 |
|---|---|---|---|
| 版本定位 | 5.7.44 为最终版本,已进入 Sustaining Support | 8.0.46 为最终版本,2026 年 4 月 EOL | 都不应作为当前新项目的长期目标版本 |
| 窗口函数 | 不支持 | 支持 | 排名、累计值、分组内排序等 SQL 更容易编写 |
| CTE | 不支持原生 WITH / 递归 CTE | 支持普通与递归 CTE | 复杂查询和树形查询可读性更好 |
| 默认认证 | 通常使用 mysql_native_password | 默认 caching_sha2_password | 旧客户端、旧驱动可能无法直接登录 |
| 默认字符集 | 历史默认通常为 latin1 | 服务器默认 utf8mb4 | 新建库表及排序规则可能与旧环境不同 |
| 数据字典 | 依赖旧式元数据文件和系统表 | 使用事务型数据字典 | 内部结构变化较大,也是升级不可随意回退的原因之一 |
| DDL | 传统实现 | InnoDB 支持原子 DDL | 服务器异常中断时,部分 DDL 操作的一致性更好 |
| 查询缓存 | 存在,但后期版本已经弃用 | 已删除 | 依赖 query_cache_* 参数的旧配置必须清理 |
| 索引功能 | 相对基础 | 支持降序索引、不可见索引等增强功能 | 索引测试和部分查询优化更方便 |
二、8.0最明显的变化,是SQL本身更好用了
对业务开发人员来说,最容易感受到的变化通常不是底层存储,而是 SQL 能力。MySQL 8.0 原生支持窗口函数和 CTE,这两项功能可以减少大量子查询、临时表和应用层计算。
窗口函数解决了什么问题
假设有一张订单表,需要按照每个用户自己的消费金额进行排名。在 MySQL 8.0 中可以直接写:
SELECT
user_id,
order_id,
amount,
ROW_NUMBER() OVER (
PARTITION BY user_id
ORDER BY amount DESC
) AS amount_rank
FROM orders;
这里的 ROW_NUMBER() 不会像普通 GROUP BY 那样把多行压缩成一行,而是保留原记录,并在每个用户内部生成排名。
类似的还有 RANK()、LAG()、LEAD()、NTILE(),以及可以作为窗口函数使用的 SUM()、AVG() 等。
CTE让复杂查询更容易读
8.0 可以通过 WITH 把中间查询结果命名。例如:
WITH paid_orders AS (
SELECT user_id, amount
FROM orders
WHERE status = 'paid'
)
SELECT
user_id,
SUM(amount) AS total_amount
FROM paid_orders
GROUP BY user_id;
5.7 通常需要改成派生表、临时表,或者把部分逻辑放到程序中处理。对于简单业务影响不大,但查询越来越复杂以后,8.0 的可维护性会明显更好。
三、字符集变化为什么经常在升级后才暴露问题
MySQL 8.0 默认服务器字符集为 utf8mb4,默认排序规则为 utf8mb4_0900_ai_ci。官方同时建议新应用明确使用 utf8mb4;传统的 utf8 在 8.0 中实际上仍指向 utf8mb3,而这一用法已经被标记为废弃。
这意味着从 5.7 升级时,不应该只检查“中文能不能正常显示”,还应该检查排序和比较结果。
例如旧库可能是:
SHOW CREATE TABLE users;
-- 可能看到类似定义:
DEFAULT CHARSET=utf8
COLLATE=utf8_general_ci
而在新的 8.0 数据库中,如果直接采用默认配置,新建表可能使用:
CHARACTER SET utf8mb4
COLLATE utf8mb4_0900_ai_ci
两套排序规则混在一个系统里,进行字符串连接、比较或者联合查询时,就可能遇到排序规则冲突,或者出现排序结果与以前不同的情况。
四、认证方式是旧程序连接8.0时最常见的兼容点之一
MySQL 8.0 默认认证插件变成了 caching_sha2_password,而不是以前常见的 mysql_native_password。官方文档明确说明了这一变化。
因此,一套运行多年的 PHP、Java、Python 或其他应用,即使 SQL 完全没有问题,也可能在数据库升级之后出现“用户名密码明明正确,却连接失败”的情况。
可以先在数据库中查看现有账户使用的认证插件:
SELECT
user,
host,
plugin
FROM mysql.user
ORDER BY user, host;
重点不是看到 caching_sha2_password 就立即修改数据库配置,而是先检查应用实际使用的数据库驱动版本。
比较稳妥的处理顺序是:
- 确认 PHP、Java、Python 等运行环境的实际版本。
- 确认 PDO、mysqli、JDBC、Connector/Python 等数据库驱动版本。
- 在测试环境建立采用
caching_sha2_password的测试账户。 - 验证连接池、定时任务、后台脚本、运维工具是否都可以连接。
- 优先升级客户端和驱动,不要把长期方案建立在强制退回旧认证插件上。
尤其是年代较久的 PHP 环境和数据库客户端,更应该把认证兼容性列为升级前的独立测试项。
五、MySQL 8.0的数据字典变化,对运维意味着什么
MySQL 8.0 引入了事务型数据字典,元数据管理方式与旧版本发生较大变化,并以此支持了原子 DDL。官方文档指出,支持原子 DDL 的操作可以把数据字典修改、存储引擎操作以及相关二进制日志写入组合成一个原子操作。
这对普通开发人员可能没有窗口函数那么直观,但对数据库升级和故障恢复很重要。
例如执行部分受支持的:
ALTER TABLE users ADD COLUMN status TINYINT NOT NULL DEFAULT 1;
在 8.0 的 InnoDB 环境中,相关元数据操作的一致性比旧体系更完整。
另一方面,这也解释了为什么不能把已经由 MySQL 8.0 升级过的数据目录简单交给 5.7 启动。官方明确指出,从 MySQL 8.0 降级到 5.7 不受支持;如果升级后必须回退,可靠方案是恢复升级之前制作并验证过的备份。
六、从5.7升级8.0,最容易踩的兼容性问题有哪些
1. 旧客户端不支持新的认证插件
这是前面提到的连接兼容问题。数据库本身正常启动,但应用可能报认证插件不支持、连接握手失败或类似错误。
2. 使用了8.0新增的保留关键字作为字段名
不同版本的关键字列表存在变化。如果旧项目把后来成为保留字的单词直接作为列名、表名或存储过程标识符,升级后 SQL 可能解析失败。MySQL 官方也把新增保留字列为 5.7 升级 8.0 时需要检查的兼容项。
例如旧项目大量存在:
SELECT rank FROM user_score;
这类名称在升级前都应该经过检查。必要时修改字段名,或者按照 MySQL 标识符规则使用反引号进行引用,而不是等生产环境报错后再逐条处理。
3. 依赖GROUP BY隐式排序
旧代码有时把 GROUP BY 同时当成分组和排序使用,这是不可靠的写法。8.0 中还删除了过去已经废弃的 GROUP BY ... ASC/DESC 语法。官方建议需要确定顺序时明确使用 ORDER BY。
正确思路是:
SELECT category_id, COUNT(*) AS total
FROM article
GROUP BY category_id
ORDER BY category_id ASC;
排序需求应该由 ORDER BY 明确表达。
4. 配置文件仍保留查询缓存参数
MySQL 5.7 的查询缓存已经处于废弃状态,而 MySQL 8.0 将其彻底删除。旧服务器配置中如果还保留大量 query_cache_* 参数,迁移时应该清理。
5. SQL模式造成历史脏数据暴露
老系统如果长期依赖比较宽松的数据写入行为,升级时也应该检查 sql_mode。MySQL 8.0 默认 SQL 模式包含 ONLY_FULL_GROUP_BY、STRICT_TRANS_TABLES、NO_ZERO_IN_DATE、NO_ZERO_DATE、ERROR_FOR_DIVISION_BY_ZERO 和 NO_ENGINE_SUBSTITUTION 等。
可以在当前服务器上执行:
SELECT VERSION();
SELECT @@GLOBAL.sql_mode;
SELECT @@SESSION.sql_mode;
重点检查代码是否存在不完整 GROUP BY、非法日期、字段长度不匹配以及依赖隐式类型转换等情况。
七、旧系统要升级,推荐按什么顺序做
官方支持从 MySQL 5.7 GA 版本升级到 8.0,并建议在跨系列升级前先把源端升级到最新的 5.7 版本。对于 5.7 系列来说,最终版本就是 5.7.44。
当前环境如果最终目标是 MySQL 8.4,也不要把“直接跳过去”想当然地当成普通原地升级路径。官方 APT 文档明确举例说明,从 5.7 向更新系列升级时,应先进入 8.0,再升级到 8.4。
步骤1:确认当前环境
先记录服务器真实状态,而不是依赖安装文档或运维人员记忆。
SELECT VERSION();
SHOW VARIABLES LIKE 'character_set_server';
SHOW VARIABLES LIKE 'collation_server';
SHOW VARIABLES LIKE 'sql_mode';
SELECT
user,
host,
plugin
FROM mysql.user
ORDER BY user, host;
同时整理应用使用的数据库驱动、ORM、备份程序、同步程序、监控软件以及主从复制结构。
步骤2:准备并验证备份
备份方式要根据数据规模和复制架构选择,可以是经过验证的物理备份,也可以是适用于当前场景的逻辑备份。核心要求不是“执行过一次备份命令”,而是确认可以恢复。
如果使用 mysqldump 做普通 InnoDB 逻辑备份,下面可以作为示例:
mysqldump \
-u root -p \
--single-transaction \
--routines \
--events \
--triggers \
--hex-blob \
--all-databases \
> /backup/mysql57-full.sql
这是备份示例,不代表所有生产环境都应该直接采用相同参数。使用 GTID、超大数据库、复杂复制拓扑或者需要很短停机时间的系统,应单独设计备份与切换方案。
另外,跨大版本迁移时不要简单把旧版本的 mysql 系统库当成普通业务库直接覆盖到新版本服务器。
步骤3:运行官方Upgrade Checker
MySQL Shell 提供 Upgrade Checker,可以检查服务器是否存在已知的升级兼容问题。官方建议在升级前使用这一工具。
例如在安装了 MySQL Shell 的管理机器上,可以执行:
mysqlsh -- util check-for-server-upgrade \
root@127.0.0.1:3306 \
--target-version=8.0.46 \
--output-format=JSON
命令会连接源数据库并输出检查结果。实际执行时应根据自己的账户、地址、配置文件以及目标版本调整参数。
重点处理:
- 已经删除的系统变量和配置参数;
- 新增保留字;
- 不兼容 SQL 语法;
- 字符集与排序规则问题;
- 表和数据字典兼容问题;
- 插件及存储引擎问题。
步骤4:复制生产数据到测试环境
不要第一次升级就直接操作正式服务器。测试环境应该尽可能使用生产数据结构以及有代表性的数据量。
升级完成后至少验证:
- 登录、注册等基础读写业务;
- 后台管理和批处理任务;
- 复杂报表 SQL;
- 定时任务;
- 数据库连接池;
- 复制或数据同步程序;
- 备份与恢复程序;
- 慢查询和关键接口响应时间。
步骤5:不要只测试“能不能运行”,还要比较执行计划
数据库版本升级以后,优化器可能针对同一条 SQL 选择不同执行计划。因此,一条 SQL 在 5.7 中执行正常,并不意味着升级后性能一定完全相同。
可以把核心查询单独整理出来,在两套环境中分别执行:
EXPLAIN
SELECT
id,
user_id,
created_at
FROM orders
WHERE user_id = 10001
ORDER BY created_at DESC
LIMIT 20;
比较索引选择、扫描行数、连接顺序和实际响应时间。对于交易、订单、内容列表、搜索等高频 SQL,这一步比单纯执行功能测试更有意义。
八、哪些情况下还会暂时保留MySQL 5.7
到了现在,继续运行 5.7 的理由通常不是“它功能更合适”,而是系统迁移成本暂时无法接受。
例如以下情况可能导致项目暂时停留在 5.7:
- 老旧商业软件明确绑定 5.7,并且厂商没有提供新版本支持;
- 应用运行在很旧的 PHP、Java 或其他运行环境中,驱动升级牵涉大量代码;
- 数据库中存在大量历史 SQL、存储过程和特殊插件,需要较长的兼容改造周期;
- 系统准备整体下线,迁移数据库的投入高于剩余维护周期。
这时可以暂时保留 5.7,但应该把它理解为遗留系统维护方案,而不是新系统版本选择。网络访问、账户权限、备份、监控和迁移计划都应该更加严格。
九、什么情况下8.0仍然有实际价值
虽然 8.0 自 2026 年 4 月已经进入 EOL,但在旧系统迁移链路中仍然可能需要接触它。
典型场景就是现有系统运行在 5.7,而最终准备迁移到 8.4 LTS。MySQL 官方升级说明采用逐个系列升级的原则,并明确给出了 5.7 先升级到 8.0、再升级到 8.4 的示例。
在这种情况下,8.0 更适合看作:
- 用于发现 5.7 时代兼容问题的迁移阶段;
- 旧应用适配现代认证、字符集和 SQL 行为的过渡环境;
- 进入 8.4 LTS 之前的版本升级节点。
也就是说,今天讨论“5.7 还是 8.0”,如果是在旧服务器升级场景中,答案通常不是“永远停留在哪一个”,而是如何安全地从 5.7 跨过 8.0,最终进入仍受支持的版本系列。
十、新项目还应该选择5.7或8.0吗
如果是 2026 年新建立的生产系统,不建议从零部署 5.7,也不建议把已经 EOL 的 8.0 当作新的长期版本基线。
MySQL 当前采用 LTS 与 Innovation 两条发布路线。LTS 面向希望功能相对稳定、维护周期较长的生产环境,而 Innovation 系列提供更新的功能变化。对于普通业务系统,如果没有明确需要快速追新功能,一般应优先评估当前受支持的 LTS 系列,例如 MySQL 8.4。
选择数据库版本时,不要只看“网上教程多不多”,而应该检查四件事情:
- 目标版本是否仍处于官方支持周期;
- 操作系统、数据库驱动和 ORM 是否支持;
- 备份、监控以及高可用组件是否兼容;
- 项目未来几年是否有足够稳定的维护路径。
十一、可以直接套用的选择结论
把前面的差异压缩成实际选择,可以按下面几种情况判断。
| 当前场景 | 更合理的处理方式 | 原因 |
|---|---|---|
| 2026 年新项目 | 不以 5.7 或 8.0 作为新的长期基线,评估受支持 LTS | 5.7 和 8.0 都已经结束主要生命周期 |
| 正在运行稳定的 5.7 老系统 | 短期可以维持,但应启动迁移计划 | 强行立即升级可能影响业务,但长期停留风险会继续增加 |
| 5.7 系统准备现代化 | 检查 5.7 → 8.0 兼容性,并继续规划到受支持版本 | 8.0 是重要的兼容性分界和升级节点 |
| 只能在 5.7 与 8.0 中二选一做短期过渡 | 通常选择 8.0,但明确它只是过渡环境 | SQL、安全、数据字典和管理能力明显强于 5.7,但自身也已 EOL |
| 第三方旧软件明确只支持 5.7 | 暂时保留 5.7,并限制暴露范围 | 应用兼容性优先,但需要备份、安全隔离和后续替换计划 |
十二、总结
MySQL 5.7 和 8.0 的差别并不只是版本号变化。8.0 增加了窗口函数、CTE、事务型数据字典和原子 DDL,引入 caching_sha2_password 作为默认认证方式,同时改变了默认字符集、排序规则,并移除了查询缓存等旧功能。因此,从 5.7 升级到 8.0 时,真正需要关注的是应用连接、SQL 语法、字符集、配置文件和执行计划的兼容性。
如果维护的是现有 5.7 系统,不必因为版本旧就未经测试直接升级。合理顺序是先整理环境和备份,再使用 Upgrade Checker 检查问题,在测试环境完成驱动、SQL 和性能验证,最后再安排生产切换。
如果讨论的是现在新建数据库,则不要再简单地把问题理解成“5.7 稳定还是 8.0 功能多”。截至 2026 年,5.7 与 8.0 都已经走完各自的主要生命周期。新项目更应该结合官方支持周期,选择仍受支持的 LTS 系列;旧项目则把 5.7 → 8.0 看成迁移链路的一部分,并规划继续进入当前受支持版本。
资料核对
本文涉及版本生命周期及升级路径的时效信息,根据 MySQL 官方发布说明和参考手册核对。
MySQL 5.7.44 为 5.7 系列最终版本,发布日期为 2023 年 10 月 25 日。
MySQL 官方 EOL 公告说明,5.7 自 2023 年 10 月 25 日进入 Oracle Lifetime Sustaining Support。
MySQL 8.0 Release Notes 说明,8.0.46 于 2026 年 4 月成为 8.0 系列 EOL 节点。
MySQL 官方支持从 5.7 GA 升级至 8.0,并建议先把源端升级到最新的 5.7 版本。
MySQL 8.4 官方文档说明 LTS 与 Innovation 两条发布路线,并建议稳定生产环境根据维护需求选择对应路线。
官方升级文档给出的跨系列示例为:从 5.7 升级到更新系列时,先升级到 8.0,再继续升级到 8.4。
免责声明:本文内容仅供参考,不代表本站观点。转载或引用请注明出处。









