必须四级对齐:服务端、数据库、表、字段全设为utf8mb4且连接层显式声明;需检查character_set_server、Navicat连接字符集、库表字段编码及SQL文件编码,并执行SET NAMES utf8mb4。

必须四级对齐:服务端、数据库、表、字段全设为 utf8mb4,且连接层显式声明,缺一不可。
检查并修正 MySQL 服务端默认字符集
Navicat 导入 Emoji 失败,第一关常卡在服务端。即使你改了库或表,只要 character_set_server 还是 utf8(即 utf8mb3),新建对象就可能继承错误编码。
- 执行
SHOW VARIABLES LIKE 'character_set_server';,确认返回值是utf8mb4 - 若不是,编辑
my.cnf(Linux)或my.ini(Windows),在[mysqld]段下确保有:character-set-server=utf8mb4 collation-server=utf8mb4_unicode_ci init_connect='SET NAMES utf8mb4' skip-character-set-client-handshake=FALSE
- 重启 MySQL 服务(
systemctl restart mysqld或服务管理器),再查一遍变量
确认 Navicat 连接层是否真正用了 utf8mb4
很多用户改完服务端和数据库,仍报 Incorrect string value,问题出在 Navicat 连接握手阶段没传对字符集——它用 utf8 去解析本该是 utf8mb4 的字节流,直接截断或报错。
- 右键连接 →「编辑连接」→「常规」页签 →「字符集」下拉选
utf8mb4(别选「自动」或utf8) - 切到「高级」页签 → 勾选「Use Unicode UTF-8」→ 在「初始化命令」栏填:
SET NAMES utf8mb4 COLLATE utf8mb4_unicode_ci; - 保存后务必「断开连接」再「重新连接」,看右下角状态栏显示的字符集是否为
utf8mb4 - 如果用命令行导入 SQL 文件,也要加参数:
mysql --default-character-set=utf8mb4 -u user -p db_name
逐级验证并修复数据库、表、字段字符集
只改数据库或只改表是常见陷阱。Emoji 存储失败往往因为某一层还残留 utf8 或 latin1,尤其是字段级——哪怕表设对了,某个 VARCHAR 字段仍可能是旧编码。
- 查库:执行
SHOW CREATE DATABASE `your_db`;,确认含DEFAULT CHARACTER SET = utf8mb4 - 查表:执行
SHOW CREATE TABLE `your_table`;,重点看末尾是否带DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci - 查字段:执行
SHOW FULL COLUMNS FROM `your_table`;,检查每个文本字段的Collation列是否为utf8mb4_unicode_ci(不是utf8_general_ci) - 批量修复表:用
ALTER TABLE `your_table` CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;(比只改 DEFAULT 更彻底) - 单独修字段(如昵称字段):
ALTER TABLE `your_table` MODIFY `nickname` VARCHAR(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
导入前必须加 SET NAMES,且注意 SQL 文件编码
即使所有层级都设对了,Navicat 导入 SQL 文件时仍可能乱码,原因有两个:SQL 文件本身是 GBK 编码保存的,或文件开头没声明字符集,导致客户端按默认编码解析语句。
- 在 SQL 文件最顶部手动加上:
SET NAMES utf8mb4;(必须是第一行,不能有空行或 BOM) - 用编辑器(如 VS Code、Notepad++)确认文件编码为 UTF-8 无 BOM;若原文件是 GBK,需先转码再导入
- Navicat「运行 SQL 文件」时,在弹窗中「字符集」下拉菜单也手动选
UTF-8,别依赖自动检测 - 导入后立刻测试插入真实 Emoji:
INSERT INTO your_table (name) VALUES ('?');,别只看导入是否“成功”,要看查出来是不是原样
最容易被忽略的是字段级字符集和连接初始化命令——服务端和库设对了,表也 CONVERT 过了,但某个 TEXT 字段仍是 utf8,或者 Navicat 连接没重连、初始化命令没生效,Emoji 就会变成 ??? 或直接报错。动手前先 SHOW VARIABLES 和 SHOW CREATE TABLE,眼见为实。


















