你是不是碰过这样的场景:项目换到 MySQL 8.0 后,一条原本在 5.7 能跑的 SQL,突然崩得体无完肤——报错代码、提示“Expression #1 not in GROUP BY”...而你一脸懵逼:明明是旧代码,咋在新版本里抛这么大的异常?现实中,这种“明明写对了,却不能执行”的情况让许多 DBA 或开发崩溃过。今天这篇文章,我们从“粗”到“精”,配对比参数,一步步演示,帮你彻底搞懂 MySQL 8.0 相比 5.7 在字符集、GROUP BY 与新功能上的重大变更,避免继续踩坑。
特性 | MySQL 5.7 | MySQL 8.0 |
---|---|---|
发布年份 | 2015 | 2018 |
社区维护结束 | 已停止支持 | 主流版本,持续更新 |
MySQL 5.7 | MySQL 8.0
5.7 默认 latin1
不支持 emoji,8.0 默认 utf8mb4,支持完整 Unicode:
-- MySQL 5.7 创建可能只支持基本字符
CREATE TABLE t1 (content VARCHAR());
INSERTINTO t1 VALUES('😀 emoji 测试');-- 会报错或乱码
-- MySQL 8.0
CREATE TABLE t2 (
content VARCHAR()CHARACTERSET utf8mb4 COLLATE utf8mb4_0900_ai_ci
);
INSERT INTO t2 VALUES('😀 emoji 测试');-- 正常存储
查询当前版本默认:
SHOW VARIABLES LIKE'character_set_server';
5.7 中统计表信息:
SELECT table_schema, table_name, table_rows
FROM information_schema.tables
WHERE table_schema='test';
8.0 新增 Performance Schema:
SELECT*
FROM performance_schema.table_io_waits_summary_by_table
WHERE OBJECT_SCHEMA='test';
性能更优,可统计访问热点、IO 等。
5.7 不支持 Role,权限只能单独 GRANT:
GRANT SELECT ON db.*TO'user1'@'%';
8.0 支持 Role:
-- 创建一个 readonly 角色
CREATE ROLE readonly;
GRANT SELECT ON*.*TO readonly;
-- 给用户分配
GRANT readonly TO'user1'@'%';
SETDE FAULT ROLE readonly TO'user1'@'%';
Role 可统一管理权限,非常适合中大型项目。
### 在容器中执行 vi 或 grep 报错
```bash
bash: vi: command not found
bash: grep: command not found
生产容器建议不安装包,用宿主机操作;若是临时演示可安装:
yum install-y vim grep
docker exec-it mysql-master bash
mysql -uroot-p
CREATE DA TABASE testdb;
USE testdb;
CREATE TABLE users (id INTAUTO_INCREMENT PRIMARYKEY, name VARCHAR());
INSERTINTO users (name)VALUES('Alice'),('Bob'),('Charlie');
验证:
CREATET EMPORARY TABLE temp_demo(id INT);
-- 在 8.0 中查看内存使用:
SELECT*FROM performance_schema.memory_summary_global_by_event_name WHERE EVENT_NAME LIKE'%temp%';
隐藏索引不会被查询优化器使用,但仍然存在,用于做灰度测试
ALTER TABLE users ADD INDEX idx_name(name);
ALTER TABLE users ALTER INDEX idx_name INVISIBLE;-- 隐藏
ALTER TABLE users ALTER INDEX idx_name VISIBLE;-- 还原
-- 提取 JSON 中的数组元素
SELECT JSON_EXTRACT('{"a":{"b":[1,2,3]}}','$.a.b[1]');
-- 返回 2
5.7 不支持,8.0 终于补上了现代 SQL 的关键特性
SELECT name, score, RANK()OVER(ORDERBY score DESC)AS rank FROM users;
WITH top_users AS(
SELECT name FROM users ORDERBY score DESCLIMIT
)
SELECT*FROM top_users;
在 5.7 中,ALTER TABLE
如果失败,可能留下半成品表结构 在 8.0 中,DDL 要么成功、要么全回滚,确保表结构一致
-- 如 ALTER TABLE 操作失败,不会影响原表结构
-- 开启密码策略
SET GLOBAL validate_password.policy = MEDIUM;
SET GLOBAL validate_password.length =;
-- 设置用户密码过期时间
ALTER USER'dba'@'%' PASSWORD EXPIRE INTERVALDAY;
功能点 | MySQL 5.7 | MySQL 8.0 |
---|---|---|
字符集 | 默认 utf8 | 默认 utf8mb4(Emoji OK) |
GROUP BY | 强限制 | 宽容优化 |
权限 | 仅用户权限 | 引入角色系统 |
临时表 | 磁盘临时表 | 内存临时表 |
索引 | 普通索引 | 支持隐藏索引 |
JSON | 基础操作 | 路径/校验函数增强 |
查询功能 | 无窗口函数/CTE | 支持窗口函数/CTE |
元数据 | 文件存储 | 内建数据字典 |
DDL | 非原子 | 原子操作 |
密码策略 | 简单策略 | 多策略、过期时间 |