MySQL测试环境需显式配置server、database、table、column、connection五层字符集均为utf8mb4,尤其客户端连接必须指定--default-character-set=utf8mb4或connect()中charset='utf8mb4',否则中文插入会乱码或失败。
MySQL 8.0 默认 character_set_server 是 utf8mb4,但很多旧部署仍为 latin1 或未显式配置。直接运行 SHOW VARIABLES LIKE 'character\_set\_server'; 查看实际值——如果返回 latin1,后续建库不指定字符集就会继承它,导致中文插入报错或乱码,根本测不出 utf8mb4 的真实行为。
实操建议:
my.cnf 的 [mysqld] 段强制声明:[mysqld] character_set_server = utf8mb4 collation_server = utf8mb4_unicode_ci
SET GLOBAL character_set_server = ...,该设置在重启后丢失,且部分客户端连接可能已缓存旧值SELECT @@cha
racter_set_server, @@collation_server;,两个值都应为 utf8mb4 和 utf8mb4_unicode_ci
用 CREATE DATABASE 不带 CHARACTER SET 子句,会继承 server 级默认值,看似省事,但一旦 server 配置被他人修改,测试结果就不可复现。必须显式锁定。
实操建议:
CREATE DATABASE charset_test CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci;
utf8(MySQL 中的别名,实际是 utf8mb3),它不支持 emoji 和部分生僻汉字utf8mb4_bin 库:CREATE DATABASE charset_test_bin CHARACTER SET = utf8mb4 COLLATE = utf8mb4_bin;——
_bin 排序规则区分大小写和字节精确匹配,对调试大小写敏感场景很关键即使 server 和库都设为 utf8mb4,如果客户端连接未声明编码,MySQL 仍按 latin1 解析传入的 SQL 字符串,导致 INSERT 中文变成问号或乱码,测试完全失效。
实操建议:
mysql --default-character-set=utf8mb4 -u root -p charset_test
connect() 里传 charset='utf8mb4':conn = pymysql.connect(
host='localhost',
user='root',
password='xxx',
database='charset_test',
charset='utf8mb4' # 关键!缺了这行就白搭
)SELECT @@character_set_client, @@character_set_connection, @@character_set_results; 三者都应为 utf8mb4
建表时若漏写 CHARACTER SET,即使库是 utf8mb4,某些旧版本 MySQL(如 5.6)可能因隐式转换规则生成 latin1 字段,导致字段级编码与预期不符。
实操建议:
CREATE TABLE t1 ( id INT PRIMARY KEY, name VARCHAR(100) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
SHOW CREATE TABLE t1; 查看 DEFAULT CHARSET 和各 VARCHAR 字段的 COLLATE 是否一致SELECT HEX(name) FROM t1; 检查十六进制值:正确 utf8mb4 中文是 4 字节(如「测」→ E6B58B),若返回 3F(问号)或 2 字节值,说明某层编码链路断了MySQL 字符集测试环境真正难的不是配参数,而是每一层(server、database、table、column、connection)都得显式对齐,少一处,测试就失真。最容易被忽略的是客户端连接时的 charset 参数——它不在配置文件里,也不在建库语句里,却决定你敲进去的 SQL 到底被当什么编码解析。