字段级字符集必须逐字段修改,Navicat的“编辑数据库”仅改库级默认值,不生效于已有表和字段;需右键表→“设计表”→底部手动为每个字段选utf8mb4及匹配collation,并确保连接层执行SET NAMES utf8mb4。
Navicat 的「编辑数据库」或右键「字符集和排序规则」只改数据库级别的 DEFAULT CHARACTER SET,它不会下推到已有表,更不会影响字段。哪怕你执行了 ALTER DATABASE db_name CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci,已存在的字段仍保持原字符集(比如 latin1),插入中文时照样变 ???。
字段字符集优先级最高:即使表设成 utf8mb4,只要某个 VARCHAR 字段显式声明了 CHARACTER SET latin1,它就按 latin1 存储和比较——这个细节常被忽略,也是乱码的根源之一。
在 Navicat 中修改单个字段的字符集,唯一可靠路径是:右键目标表 → 「设计表」→ 切换到底部「表选项」→ 找到对应字段 → 在「字符集」和「排序规则」下拉框中手动选择(如 utf8mb4 + utf8mb4_unicode_ci)→ 保存。
utf8mb4_* 选项,说明 MySQL 服务端未启用该字符集,需先检查 my.cnf 中是否配置了 character-set-server=utf8mb4
ALTER TABLE `t` MODIFY `name` VARCHAR(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci 的语句,注意它只改该字段,不波及其他Navicat 没有真正意义上的“批量修改字段字符集”图形入口。所谓「批量编辑」功能(如多选字段后右键)仅支持修改字段名、类型、长度等基础属性,不包含字符集和排序规则字段。
真要批量处理,只能写 SQL:
ALTER TABLE `t` MODIFY `col1` VARCHAR(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci,MODIFY `col2` TEXT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci,MODIFY `col3` ENUM('a','b') CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
注意:ENUM 和 SET 类型字段必须显式重申枚举值,否则会丢失定义。
字段设对了 ≠ 万事大吉。客户端与服务端之间传输时用的字符集由连接层决定,和字段设置完全解耦。
必须检查 Navicat 连接属性中的「高级」→「初始化命令」是否填了:
SET NAMES utf8mb4 COLLATE utf8mb4_0900_ai_ci;
然后连上库执行:
SELECT @@character_set_client, @@character_set_connection, @@character_set_results;
三者都应返回 utf8mb4。只要其中任一为 latin1 或 utf8(非 utf8mb4),插入中文仍会失败。
最容易被跳过的环节就是这里:字段、表、库全设对了,就因为少了一句 SET NAMES,整条链路还是断裂的。