必须同步统一SQL文件编码、连接初始化和目标字段三者均为utf8mb4,缺一不可;任一环节为utf8(utf8mb3)或latin1,中文、emoji必乱码或报错。

跨操作系统迁移 Navicat 时,字符集编码冲突不是“偶尔发生”,而是只要涉及中文、emoji 或非 ASCII 字符,就大概率在三个环节同时出问题:SQL 文件读取、数据库连接初始化、目标字段定义。三者只要有一处是 utf8(即 utf8mb3)或 latin1,而其他两处是 utf8mb4,乱码就必然出现。
确认并统一 SQL 文件的真实编码(不是 Navicat 界面里选的那个)
Navicat 导入窗口的「编码」下拉菜单只控制文件字节如何解码,不校验文件本身是否真为该编码。选错就直接报语法错误或插入后查出来是 ???。
- 用
VS Code打开 SQL 文件,右下角看状态栏:必须显示UTF-8(不是UTF-8 with BOM),否则另存为UTF-8 (no BOM) - Linux/macOS 下用命令验证:
file -i your.sql;Windows 别信chcp,它和文件编码无关 - Navicat v16+ 导入弹窗中,“使用 UTF-8 编码读取文件”必须手动勾选——默认可能关闭
强制连接层使用 utf8mb4(SET NAMES 不会自动执行)
SQL 文件导入绕过常规连接初始化流程,SET NAMES utf8mb4 不会自动运行。即使文件编码正确、目标表也设了 utf8mb4,只要会话层还是 latin1,MySQL 就按 latin1 解析你的 INSERT 语句。
- 在 Navicat 当前连接的查询窗口中,先手动执行:
SET NAMES utf8mb4; - 更稳妥:右键连接 → “连接属性” → “高级”页签 → 勾选“使用 MySQL 字符集”,并在“初始化命令”填入:
SET NAMES utf8mb4; - 执行后立刻查:
SHOW VARIABLES LIKE 'character_set%';,确认character_set_client、character_set_connection、character_set_results三者都是utf8mb4
检查并修正目标表字段的字符集定义
即使导入预览正常、没报错,SELECT 出来仍是 ???,90% 是因为字段定义里没写死 CHARACTER SET utf8mb4,还在用 utf8(utf8mb3)或 latin1。
- 运行:
SHOW CREATE TABLE `your_table`;,重点看每个中文字段末尾有没有CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci - 如果没写,
CONVERT TO CHARACTER SET utf8mb4可能漏掉TEXT、MEDIUMTEXT类型,必须单独改:ALTER TABLE your_table MODIFY COLUMN content TEXT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci; - 旧库建库时没指定字符集,
character_set_database可能是utf8,新建表默认继承——不能只靠CONVERT TO兜底
最容易被忽略的是:三处必须全对齐——文件编码、连接初始化、字段定义。缺一不可。哪怕只有一处是 utf8(utf8mb3),emoji 和生僻汉字就会变成 Incorrect string value 错误或方块。











