MySQL 5.7 升 8.0 后默认字符集变了

FreeGuideOnline 最新 2026-07-06

sql SHOW VARIABLES LIKE 'character_set_server'; SHOW VARIABLES LIKE 'collation_server';

在 8.0 下应该看到:

+----------------------+--------------------+ | Variable_name | Value | +----------------------+--------------------+ | character_set_server | utf8mb4 | | collation_server | utf8mb4_0900_ai_ci | +----------------------+--------------------+


### 查看所有数据库和表的字符集情况
快速扫描全部数据库的默认字符集:
```sql
SELECT SCHEMA_NAME, DEFAULT_CHARACTER_SET_NAME, DEFAULT_COLLATION_NAME
FROM INFORMATION_SCHEMA.SCHEMATA
WHERE SCHEMA_NAME NOT IN ('mysql', 'information_schema', 'performance_schema', 'sys');

找出所有表及列的字符集(替换 your_database):

SELECT TABLE_SCHEMA, TABLE_NAME, COLUMN_NAME, CHARACTER_SET_NAME, COLLATION_NAME
FROM INFORMATION_SCHEMA.COLUMNS
WHERE TABLE_SCHEMA = 'your_database' AND CHARACTER_SET_NAME IS NOT NULL;

将单个表从 utf8 转换为 utf8mb4

ALTER TABLE your_table CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci;

该语句会同时转换数据并重建表,大表执行时间较长,务必在低峰期操作。

批量转换整个数据库的字符集

没有直接的“一键转换整个库”命令,但可用脚本动态生成 ALTER 语句:

SELECT CONCAT('ALTER TABLE ', TABLE_SCHEMA, '.', TABLE_NAME, 
              ' CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci;')
FROM INFORMATION_SCHEMA.TABLES
WHERE TABLE_SCHEMA = 'your_database' AND TABLE_TYPE = 'BASE TABLE';

将输出结果复制执行;转换完毕后,别忘了修改数据库默认字符集:

ALTER DATABASE your_database CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci;

处理字符集升级中的排序规则冲突

如果业务代码或连接器依赖 utf8_general_ci 的行为(如排序、区分大小写等),盲目改为 utf8mb4_0900_ai_ci 可能产生细微差异。推荐做法:

  • 新应用直接采用 utf8mb4 + 新排序规则;
  • 旧系统迁移时,可先用 utf8mb4 加上兼容旧行为的排序规则 utf8mb4_general_ci,例如:
    ALTER TABLE users CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;
    
    这样既支持 4 字节字符,又保留了与 5.7 类似的排序习惯。后期再逐步替换为 0900 系列。

客户端连接字符集的注意事项

确保应用连接串显式指定字符集,避免依赖服务器默认值。例如在 JDBC URL 中:

jdbc:mysql://localhost:3306/db?useSSL=false&characterEncoding=UTF-8&connectionCollation=utf8mb4_0900_ai_ci

或者在 MySQL 客户端中:

SET NAMES utf8mb4 COLLATE utf8mb4_0900_ai_ci;

使用 MySQL 升级检查工具提前发现问题

官方提供了 mysqlcheckmysql_upgrade(8.0.16后无需运行,但逻辑已纳入服务器),建议在升级前执行检查:

mysqlcheck -u root -p --all-databases --check-upgrade