根本原因是utf8mb4未全链路启用:文件编码、navicat连接设置、mysql数据库/表字符集、客户端显示环境必须全部统一为utf8mb4,缺一不可,否则生僻字因需4字节编码而被截断或替换为?。

跨操作系统导入数据时,Navicat 中文生僻字乱码的根本原因不是“系统不同”,而是 utf8mb4 未被全链路启用 —— Windows 下的 GBK、macOS 默认 UTF-8、Linux 终端 locale 设置不一致,只是暴露问题的表象。
为什么生僻字比常用中文更容易乱码
生僻字(如「䶮」「龘」「?」)需要 4 字节 UTF-8 编码,而 MySQL 的旧 utf8 字符集只支持最多 3 字节,会直接截断或替换为 ?。即使你看到“中文正常”,只要含生僻字就可能已损坏。
- 用
SHOW VARIABLES LIKE 'character_set%'查,若character_set_client或character_set_database显示utf8(非utf8mb4),生僻字必然丢 - Navicat 导入 Excel 或 CSV 时选了
UTF-8却没勾UTF-8-BOM,Windows 下常误判为 ANSI/GBK,导致生僻字字节流被错解 - 目标表字段定义里写的是
VARCHAR(255) CHARACTER SET utf8,哪怕连接层是utf8mb4,存进去也会被截断
导入前必须验证的三个 utf8mb4 落点
漏掉任意一个,生僻字就不可逆损坏。
- 数据库级:运行
SHOW CREATE DATABASE your_db;,确认输出中含CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci - 表级:运行
SHOW CREATE TABLE your_table;,字段定义不能只写VARCHAR,必须显式带CHARACTER SET utf8mb4;若无,执行ALTER TABLE your_table CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci; - 连接级:右键 Navicat 连接 →「编辑连接」→「高级」→「MySQL 字符集」选
utf8mb4,并勾选「使用 MySQL 字符集」;初始化命令填SET NAMES utf8mb4;
Excel / CSV 文件编码必须与 Navicat 导入设置严格对齐
Windows 上用 Excel 另存为 CSV,默认是 GBK(代码页 936);macOS Numbers 或 LibreOffice 默认导出为无 BOM 的 UTF-8;两者在 Navicat 里选错编码,生僻字第一个字节就解错。
- 最稳做法:在 Excel 中「另存为 → CSV UTF-8(逗号分隔)」——这个选项生成的是带 BOM 的 UTF-8,Navicat 能 100% 识别
- 若源文件来自 WPS 或老旧 Excel,用 VS Code 打开 CSV,右下角看真实编码:显示
GBK就在 Navicat 导入向导中选GBK,别碰「自动」 - 不要信文件后缀或 Excel 界面语言:.xlsx 是 ZIP 容器,内部 XML 文本编码独立存在,Navicat 不读 Excel 元数据,只靠你手动指定
导入后立即验证生僻字是否存活
别只查 SELECT * FROM table LIMIT 10 —— 那些字可能已在传输层或存储层被静默替换。
- 执行
SELECT HEX(name), name FROM your_table WHERE name LIKE '%龘%';,正确应返回类似EDA7A4(UTF-8 四字节十六进制),若返回3F3F(即??)说明已损坏 - 在 Navicat 查询结果窗口右键 →「复制为 → HTML」粘贴到浏览器,看是否渲染正常;终端类客户端(如 MySQL CLI)可能因 locale 不支持而显示方块,不代表数据库里存错了
- 真正可靠的验证是导出为新 CSV:右键表 →「导出向导」→ 编码选
UTF-8-BOM→ 用 VS Code 打开导出文件,确认生僻字原样存在
生僻字乱码往往没有报错提示,它安静地把「䶮」变成「?」再变成空格,等你上线才发现用户姓名全丢了。关键不是“选对编码”,而是让 utf8mb4 从文件字节、Navicat 解码器、MySQL 连接层、表结构定义、甚至客户端显示环境,全部咬合到位。











