必须先确认mysql版本≥5.5.3(推荐≥5.7.7)且启用innodb_large_prefix、设置innodb_file_format为barracuda,再检查并转换utf8表为utf8mb4,同时更新列、索引等依赖项,执行前备份、禁用外键检查、逐条执行alter table,并验证表与字段级字符集及排序规则,最后手动核查视图、存储过程等元数据。

直接执行批量转换前,必须先确认 MySQL 版本 ≥ 5.5.3(推荐 ≥ 5.7.7),且 innodb_large_prefix 已启用、innodb_file_format 为 Barracuda,否则 utf8mb4 的 4 字节索引可能触发 Specified key was too long 错误。
检查当前表的字符集和排序规则
先查清哪些表还在用 utf8(实际是 utf8mb3),避免误操作已升级的表:
SELECT table_schema, table_name, table_collation
FROM information_schema.tables
WHERE table_schema NOT IN ('mysql', 'information_schema', 'performance_schema', 'sys')
AND table_collation LIKE 'utf8%';
注意:table_collation 显示 utf8_general_ci 或 utf8_unicode_ci 就代表该表默认使用 utf8;但列级字符集可能不同,所以后续仍需检查列。
生成并执行 ALTER TABLE 转换语句
不能只改表默认字符集,必须同时更新列、索引、存储过程等所有依赖项。推荐用以下查询生成安全的 ALTER TABLE 语句:
SELECT CONCAT('ALTER TABLE `', table_schema, '`.`', table_name,
'` CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;')
FROM information_schema.tables
WHERE table_schema = 'your_database_name'
AND table_collation LIKE 'utf8%';
执行前务必做三件事:
- 备份整个库(
mysqldump -u root -p --databases your_database_name > backup.sql) - 在会话中临时设置:
SET FOREIGN_KEY_CHECKS = 0;(避免外键约束中断转换) - 逐条执行生成的
ALTER TABLE,不要拼成一个大语句——单表失败不影响其余
如果某张表报错 Row size too large,说明存在 TEXT/BLOB 列 + 长索引组合,需先缩小索引长度或改用前缀索引。
验证转换结果与修复潜在问题
转换后必须验证两层:
第一层看表结构是否生效:
SHOW CREATE TABLE your_table_name;
确认输出中出现 DEFAULT CHARSET=utf8mb4 和 COLLATE=utf8mb4_unicode_ci;第二层查字段级字符集:
SELECT column_name, character_set_name, collation_name FROM information_schema.columns WHERE table_schema = 'your_database_name' AND table_name = 'your_table_name' AND character_set_name = 'utf8';
若仍有 character_set_name = 'utf8',说明该列未被 CONVERT TO 覆盖(例如显式定义了 CHARACTER SET utf8),需单独执行:
ALTER TABLE your_table_name MODIFY column_name VARCHAR(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
另外,utf8mb4 下 utf8mb4_unicode_ci 是推荐排序规则,但旧应用若依赖 utf8_general_ci 的排序行为,需同步测试 ORDER BY 和 WHERE 模糊匹配是否一致。
真正麻烦的不是执行命令,而是那些没出现在 information_schema.tables 里的元数据:视图、存储过程、函数体内的硬编码字符串、客户端连接参数(character_set_client 等)——它们全得手动核对,漏掉一个就可能让 emoji 存进去变成 ?。











