ALTER TABLE ... CONVERT TO 才真正重编码数据,而 ALTER TABLE ... CHARACTER SET 仅修改表级元数据;GUI工具通常只执行后者,导致乱码和排序异常,安全迁移须分备份、确认、逐列修改、验证四步。
MySQL 修改表字符集和 Collation 的实际操作路径
直接改 character set 和 collation 不等于数据“自动转码”,很多同学执行完 alter table ... convert to 后发现中文乱码、排序异常,本质是没分清「元数据变更」和「内容重编码」的区别。
ALTER TABLE ... CONVERT TO vs ALTER TABLE ... CHARACTER SET 的区别
这是最容易踩的坑:两个命令表面相似,行为完全不同。
-
ALTER TABLE t CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci:重编码所有CHAR/VARCHAR/TEXT列,把列中存储的字节按旧编码解读、再按新编码重新编码 —— 这才是真转换 -
ALTER TABLE t CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci:只改表默认字符集和排序规则,已有列的定义、存储内容、索引行为全都不变 - 如果原表是
latin1但字段里存了 UTF-8 字节(常见于历史错误导入),用CONVERT TO会二次错解,必须先用ALTER COLUMN ... TYPE强制指定旧编码再转
可视化工具(如 phpMyAdmin、DBeaver)点“修改 Collation”时到底干了什么
绝大多数 GUI 工具点击保存后,背后执行的是 ALTER TABLE ... CHARACTER SET 类命令 —— 它只改表级元数据,不碰列内容。这意味着:
- 已有的
VARCHAR(255)字段仍按原来编码解析,查询WHERE name = '张'可能因 collation 不匹配漏匹配 - 新增字段会继承新 collation,但老字段还是老规则,
ORDER BY或JOIN时隐式转换可能报Illegal mix of collations - 真正安全的做法是:先用
SHOW CREATE TABLE t看清当前各列的COLLATE,再逐列用MODIFY COLUMN显式指定
一步到位的安全迁移步骤(含验证)
别信“点一下就全好”的幻觉。生产环境必须分三步走:
- 备份:运行
mysqldump --no-create-info --skip-triggers db t > data.sql单独导出数据,避免结构导出时带错编码 - 确认现状:查
SHOW FULL COLUMNS FROM t和SELECT DEFAULT_COLLATION_NAME FROM information_schema.SCHEMATA WHERE SCHEMA_NAME='db' - 逐列升级:
ALTER TABLE t MODIFY c1 VARCHAR(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci,尤其注意TEXT类型要加CONVERT TO才生效 - 验证:插入含 emoji 和多语言的测试值,执行
SELECT c1, HEX(c1) FROM t看十六进制是否符合 UTF-8 编码规律(如中文应为E4B8AD起头)
Collation 不是开关,是参与比较、排序、索引构建的运行时规则;改了表级设置,不等于所有列都立刻按新规则工作。最麻烦的永远是混合了不同 collation 的旧表,这时候光靠可视化操作只会让问题更隐蔽。

















