SHOW CREATE TABLE your_table 是唯一可靠方式,需重点检查 ENGINE=InnoDB DEFAULT CHARSET=utf8mb4(表级)和每个 VARCHAR 字段末尾是否显式声明 CHARACTER SET utf8mb4(字段级),字段若未显式定义则继承表默认,但手动修改过即脱离继承。
查清表和字段实际用的字符集
show create table `your_table` 是唯一可靠方式。别信“表默认字符集”——字段可能 individually 被定义成 latin1 或 utf8,哪怕表头写着 default charset=utf8mb4。重点看两处:engine=innodb default charset=utf8mb4(表级),以及每个 varchar 字段声明末尾是否带 character set utf8mb4(字段级)。如果字段没显式声明,就继承表默认;但一旦手动改过某字段,它就脱离继承了。
ALTER TABLE CONVERT TO 不等于安全转换
ALTER TABLE `t` CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci 会重写所有字段、索引、注释,但前提是原始数据本身没被错误编码存入。如果字段之前是 latin1 存了 UTF-8 字节(典型“双重编码”),这条命令会让乱码固化。正确做法是:先确认数据是否真实损坏——用 SELECT HEX(col) 看中文字段值是否为合法 UTF-8 编码(如 E4B8AD 表示“中”);若 HEX 结果是 C3A4C2B8C2AD 这类,说明已损坏,不能直接 CONVERT,得先用 CONVERT(CAST(CONVERT(col USING latin1) AS BINARY) USING utf8mb4) 类似方式抢救。
Navicat 导入前必须设对连接字符集
即使表和字段全设成 utf8mb4,Navicat 导入时仍可能用 latin1 解析源文件字节流,导致插入问号。必须在连接右键 → “编辑连接” → “高级” → 勾选 Override default charset 并选 utf8mb4。注意:utf8 不可用——MySQL 的 utf8 是伪 UTF-8,不支持 emoji 和部分汉字;且 Navicat v12 以前版本下拉菜单里没有 utf8mb4,需升级或手动在连接字符串加 charset=utf8mb4 参数。
导出 SQL 文件时建表语句缺 CHARACTER SET utf8mb4
Navicat 导出的 CREATE TABLE 语句若没带 DEFAULT CHARSET=utf8mb4,恢复到另一台 MySQL(尤其 character_set_server=latin1 的旧实例)时,表会按服务端默认创建,字段值一插就变问号。导出前务必:取消勾选 Add CREATE DATABASE statement(避免生成无字符集的建库语句),并检查导出 SQL 中每条 CREATE TABLE 是否含 ENGINE=... DEFAULT CHARSET=utf8mb4;没有就手补,别依赖“导出编码选了 UTF-8”——文件编码 ≠ 建表语句声明的字符集。
CONVERT TO 是双刃剑,原始数据编码状态不明时优先用字段级 MODIFY 操作。











