必须用ALTER TABLE ... CONVERT TO CHARACTER SET utf8mb4语句而非Navicat“设计表”GUI操作,因后者仅修改字段定义不重编码数据、不同步表默认字符集,易致乱码;执行前需确认字符集为utf8mb4、清理非法字节、检查建表语句及连接层、导出导入设置。
Navicat里执行ALTER TABLE CONVERT TO CHARACTER SET utf8mb4
直接在navicat中改表字符集,不能只点点菜单——必须用alter table ... convert to character set语句。navicat的「设计表」界面只能改单个字段的character set,但不会自动更新表默认字符集、索引、注释或已有数据的编码,容易漏掉关键环节。
执行前先确认目标字符集是utf8mb4(不是utf8),否则emoji和部分汉字仍会丢:
- 右键连接 → 「查询」→ 新建查询,粘贴:
ALTER TABLE `your_table_name` CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci; - 运行后检查是否报错;若提示
Incorrect string value,说明表里已有非法字节(比如旧latin1存的中文),需先清理或转义 - 执行完再查
SHOW CREATE TABLE `your_table_name`;,确认DEFAULT CHARSET=utf8mb4且所有VARCHAR字段都带CHARACTER SET utf8mb4
为什么“设计表”里改字段字符集不管用
在Navicat「设计表」里给某个字段选utf8或utf8mb4,只影响该字段定义,不触发数据重编码,也不同步修改表级默认值。更麻烦的是:如果表本身DEFAULT CHARSET=latin1,新字段即使设了utf8mb4,插入时仍可能被隐式转换。
常见错误现象:
- 字段属性显示
utf8mb4,但SELECT HEX(column)看到还是CEB9这类latin1编码字节 - 新增记录正常,老数据仍是问号或乱码
- 导出SQL时建表语句仍写
DEFAULT CHARSET=latin1
根本原因:Navicat的GUI操作没调用CONVERT TO,只是发了MODIFY COLUMN,不碰存量数据。
批量改多张表别手动点,用脚本生成SQL
一张表一张表去点「设计表」改,不仅慢,还容易漏。更可靠的做法是先查出要改的表,再生成统一CONVERT语句:
在查询窗口运行:
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_db_name'
AND (table_collation NOT LIKE 'utf8mb4%' OR table_charset != 'utf8mb4');
复制结果里的所有ALTER TABLE语句,一次性执行。注意:
- 别在生产库直接跑,先在测试库验证
- 大表执行会锁表(尤其MySQL 5.7及以前),建议在低峰期操作
- 如果表有全文索引,
CONVERT TO可能失败,得先删索引、转完再重建
改完表还得检查连接层和导入/导出设置
表结构改完了,不代表万事大吉。Navicat的连接层、导出SQL、导入CSV,三处编码若没对齐,照样乱码:
- 右键连接 → 「编辑连接」→ 「高级」→ 勾选「使用自定义字符集」→ 手动输
utf8mb4(下拉菜单不可信) - 「初始化命令」填
SET NAMES utf8mb4;,确保每次连接都生效 - 导出SQL时,「文件字符集」选
UTF-8(无BOM),但更要紧的是检查导出内容里是否有DEFAULT CHARSET=utf8mb4 - 导入CSV/Excel时,向导里选的编码必须和文件真实编码一致(比如Excel另存为CSV UTF-8时带BOM,就得选
UTF-8-BOM)
最容易被忽略的是:改完表后没重启Navicat连接,或没关掉「查询结果缓存」,导致旧编码结果还在网格里缓存着,以为没生效。











