navicat查询结果导出乱码的根本原因是字符编码在“数据库→navicat内存→导出文件”链路中未对齐,需同步配置连接层utf8mb4、导出时选utf-8(无bom)或utf-8 with bom(供excel双击打开)、确保建库建表语句显式声明character set = utf8mb4,并关闭查询结果缓存。
navicat 查询结果导出乱码,不是文件写坏了,而是字符编码在“数据库 → navicat 内存 → 导出文件”链路上至少有一环没对齐。改完连接编码不等于导出就正常——导出动作本身有独立的编码开关,且 excel 等工具打开时还会二次解码。
导出向导里的「编码」下拉框该选哪个
这个选项决定文件字节流怎么落盘,和你本地用什么编辑器打开无关,但直接影响别人或后续导入能否正确解析:
- 选
UTF-8:VS Code、Notepad++、Sublime 默认识别的格式(无 BOM),适合开发/导入场景 - 选
UTF-8 with BOM:仅当你必须双击用 Excel 打开时才选,Excel 依赖开头三字节EF BB BF才认得这是 UTF-8 - 别选
Unicode或留空:Navicat 里这两个实际对应 Windows-1252 或系统 locale,在中文环境基本必乱 - 不确定原始编码?用
file -i your.sql(macOS/Linux)或xxd your.sql | head -1看头三字节是否为ef bb bf
导出 SQL 文件里建库建表语句没带 utf8mb4 声明
即使你导出时选了 UTF-8,如果生成的 SQL 里 CREATE DATABASE 或 CREATE TABLE 没显式声明字符集,MySQL 恢复时会按服务端默认 character_set_server(常为 latin1 或旧版 utf8)创建对象,插入中文就报 Incorrect string value:
- 导出前先查服务端默认字符集:
SHOW VARIABLES LIKE 'character_set_server';,如果不是utf8mb4,需先改 - 导出向导中取消勾选「添加 CREATE DATABASE 语句」,避免生成不含
CHARACTER SET = utf8mb4的建库语句 - 手动补全建库语句:
CREATE DATABASE `db_name` CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci; - 检查导出的
CREATE TABLE末尾是否有ENGINE=InnoDB DEFAULT CHARSET=utf8mb4,没有就手补
导出到 Excel 时中文注释或字段名变 館须 这类乱码
这不是数据丢了,是 Navicat 在导出过程中把元数据(比如 COLUMN_COMMENT)当成 ANSI 字符串处理,把 UTF-8 多字节序列当单字节拆开再写入 Excel —— 尤其在 Windows(默认代码页 GBK)连 UTF-8 数据库时 100% 复现:
- 优先导出为
xlsx格式(不是 CSV),xlsx 本身支持 Unicode,绕过编码协商环节 - 如果必须导 CSV:用 Notepad++ 打开导出的 CSV,菜单「编码 → 转为 UTF-8-BOM」另存,再双击 Excel 打开
- 更稳做法:Excel 新建空白表 → 「数据」→「自文本或 CSV」→ 选文件 → 在导入预览页手动选编码
65001 UTF-8→ 加载 - 别依赖 Navicat 右键表 → 导出向导 → Excel,老版本(v15 及以前)对元数据字符集处理有硬伤,改用查询结果导出更可控
导出后 Excel 里显示方块,但 VS Code 里看是好的
这说明数据本身没问题,问题出在 Excel 的自动编码探测失败。它看到无 BOM 的 UTF-8 文件,直接按系统 ANSI(如 Windows-1252 或 GBK)去解码,把一个中文的 3 字节序列当成 3 个非法字符渲染成方块:
- VS Code 能正确识别,是因为它有更强的编码探测逻辑(比如检测
SET NAMES utf8mb4、INSERT INTO ... VALUES ('中文')这类上下文) - 根本解法不是换编辑器,而是让 Excel “知道”该用什么编码:导出时选
UTF-8 with BOM,或导出后用 Notepad++ 补 BOM - 注意:补 BOM 后文件大小会多 3 字节,某些严格校验 BOM 的脚本(如某些 Python 导入工具)可能报错,要提前测试
最容易被忽略的是:Navicat 的「查询结果缓存」会固化旧编码解析结果。哪怕你改完所有设置、重启软件,只要没关掉「工具 → 选项 → 查询 → 启用查询结果缓存」,它仍可能用上次乱码的缓存渲染导出内容——关掉它,再重新执行查询,再导出。











