MySQL 8.0默认字符集改为utf8mb4而非latin1,是因utf8mb4完整支持4字节Unicode字符(如emoji、生僻汉字),而latin1和MySQL旧utf8(即utf8mb3)仅支持最多3字节字符,无法存储此类内容,插入会报Incorrect string value错误。

MySQL 8.0 默认用 utf8mb4,5.7 默认是 latin1 —— 这不是“更好用”,而是行为突变的起点。很多升级后乱码、查询变慢、大小写匹配失效,根源都在这个默认值切换上。
为什么 SHOW CREATE TABLE 看着是 utf8mb4,但 SELECT 仍乱码?
因为 character_set_server 是 utf8mb4,不代表连接层、数据库、表、字段也全是 utf8mb4。常见断点在:
- 客户端连接没设对:JDBC URL 缺
characterEncoding=utf8mb4,或 PHP 的mysqli_set_charset($conn, 'utf8mb4')没调用 - 旧表字段仍是
latin1或utf8(即 utf8mb3):执行SELECT table_schema, table_name, column_name, character_set_name FROM INFORMATION_SCHEMA.COLUMNS WHERE character_set_name IN ('latin1', 'utf8');能揪出它们 - 字段级 collation 优先于表级:即使表声明了
COLLATE utf8mb4_unicode_ci,某列若显式定义为VARCHAR(100) CHARACTER SET latin1 COLLATE latin1_swedish_ci,那它就按 latin1 解析
ALTER TABLE ... CONVERT TO CHARACTER SET utf8mb4 为什么让 WHERE name = 'abc' 突然匹配到 'ABC'?
因为这条命令没指定 COLLATE,MySQL 自动套用当前字符集的默认排序规则 —— 在 8.0 就是 utf8mb4_0900_ai_ci(不区分大小写、不区分重音)。而你原来可能用的是 utf8_bin 或 utf8mb4_bin。
面向 CRM 系统的 MySQL 8 数据库模式设计。当用户需要为客户关系管理(CRM)系统设计、评审、优化或生成数据库模式时,应使用此项技能。
- 原字段是
CHARACTER SET utf8 COLLATE utf8_bin→ 区分大小写 →'Abc' != 'abc' - 执行
CONVERT TO CHARACTER SET utf8mb4后 → 变成utf8mb4_0900_ai_ci→'Abc' = 'abc' - 正确写法是:
ALTER TABLE user MODIFY name VARCHAR(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin;(如需保持二进制比较)
从 5.7 升级到 8.0,为什么 ORDER BY 中文结果顺序变了?
不只是字符集换,排序规则内核也换了:utf8mb4_general_ci(5.7 常用)和 utf8mb4_0900_ai_ci(8.0 默认)对中文的权重计算逻辑不同。哪怕都标着 “_ci”,实际排序序列可能错位。
- 比如字段值包含 “张三”、“李四”、“王五”,在 5.7 下按拼音首字母排,在 8.0 下可能因 Unicode 9.0 新增的排序权重而穿插
- JOIN 多表时若两边 collation 不一致,会直接报
Illegal mix of collations - 验证方法:对同一字段分别执行
SELECT name FROM t ORDER BY name COLLATE utf8mb4_general_ci;和ORDER BY name COLLATE utf8mb4_0900_ai_ci;对比结果
最易被忽略的其实是字段级 collation —— 它能覆盖表级、数据库级甚至 server 级设置,而且 SHOW CREATE TABLE 输出里容易一眼扫过。升级前逐列检查 INFORMATION_SCHEMA.COLUMNS 的 collation_name 字段,比事后调参省力十倍。










