navicat 还原 sql 文件乱码的根本原因是文件编码、连接字符集与数据库字符集三者未对齐:需正确选择 utf-8 或 utf-8 with bom、在连接高级设置中启用 utf8mb4 并配置初始化命令 set names utf8mb4,同时确保目标库和表均为 utf8mb4。
navicat 还原 sql 文件时出现字符集乱码,根本原因不是文件“坏了”,而是 navicat 读取文件的编码方式和 mysql 执行时的字符集上下文没对齐——两者错位一拍,中文就变问号、方块或 incorrect string value 错误。
Navicat 导入时选错编码:UTF-8 vs UTF-8 with BOM
Navicat 的「运行 SQL 文件」弹窗右下角那个编码下拉框,不是摆设,是第一道关卡。它只管把文件字节流按你选的规则解码成文本,解错了,后面全错。
- 选
UTF-8:适用于 VS Code、Notepad++、Sublime 等现代编辑器默认保存的格式(无 BOM) - 选
UTF-8 with BOM:仅当文件由 Windows 记事本「另存为 → UTF-8」生成(头三字节是EF BB BF),否则会把 BOM 当作非法 SQL 执行,报错如SET NAMES utf8mb4 - 别信「自动检测」:Navicat 不识别
SET NAMES或文件内注释,自动检测大概率误判为 GBK - 不确定有没有 BOM?终端执行:
xxd your.sql | head -1,开头是00000000: efbb bf...就带 BOM
连接层字符集没设对:character_set_client 还是 latin1
即使文件解码正确,Navicat 把 SQL 发给 MySQL 时,仍要用一个会话级字符集去解释这些文本。如果连接初始化没设好,MySQL 默认用 latin1 解析整段 SQL,哪怕里面写着 CHARACTER SET utf8mb4,也会先错解再存,造成双乱码。
- 右键连接 → 编辑连接 → 「高级」页 → 勾选「使用自定义字符集」→ 下拉选
utf8mb4(不是utf8) - 同一页面 → 「初始化命令」框里填:
SET NAMES utf8mb4;(注意分号) - 连上后立刻执行:
SHOW VARIABLES LIKE 'character\_set%';,确认character_set_client、character_set_connection、character_set_results全是utf8mb4 - 底部状态栏若显示
latin1或空白,说明设置没生效,重启 Navicat 再试
SQL 文件自带的 SET NAMES 反而坏事
很多人在 SQL 文件开头手动加 SET NAMES utf8mb4; 想“保险”,结果还原失败。因为 Navicat 的「运行 SQL 文件」不模拟真实交互式连接,这类语句可能被跳过、延迟生效,或只影响后续部分,对前面的 CREATE TABLE ... CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci 完全无效。
- 还原前删掉文件开头所有
SET NAMES、SET CHARSET、SET collation_connection行 - 尤其警惕备份工具(如 mysqldump)自动生成的
/*!40101 SET NAMES utf8mb4 */注释——它虽是注释,但 Navicat 仍会尝试执行,且在旧版 MySQL 上可能报错 - 真正起作用的是连接配置里的初始化命令,不是文件内容
表层和服务层没统一:建表写了 utf8mb4,但库还是 utf8
还原成功不代表数据安全。如果目标库本身是 utf8(MySQL 的伪 utf8,最大 3 字节),而 SQL 文件里建表指定了 CHARACTER SET utf8mb4,MySQL 会静默降级为 utf8,导致 emoji 或生僻字插入时直接报 Incorrect string value。
- 连上目标库后执行:
SHOW CREATE DATABASE your_db;,确认DEFAULT CHARACTER SET是utf8mb4 - 若不是,执行:
ALTER DATABASE `your_db` CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci; - 已有表检查:
SHOW CREATE TABLE your_table;,字段级编码也可能残留utf8,需用ALTER TABLE `t` CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci; - MySQL 配置文件(
my.cnf)中必须有:character_set_server = utf8mb4,否则新库默认仍是utf8
最容易被忽略的一点:Navicat 的「字符集」下拉菜单和「初始化命令」是两套独立机制,只改其中一个几乎必出问题;而 SQL 文件是否带 BOM,又是一个隐藏开关——这三个点只要漏掉一个,乱码就会准时出现。











