Prompts-MCP 686 skills · ai / design / design-pattern / framework / fundamentals / habit / lang / tech-selection /mcp/sse
framework framework/mysql/schema/charset-utf8mb4.md medium

mysql-charset-utf8mb4

MySQL 字符集统一 utf8mb4 — utf8 是阉割版存不下 emoji/4 字节字符,库表列与连接全用 utf8mb4,JOIN 两列 collation 须一致否则隐式转换使索引失效。Use when 建库建表定字符集 / 排查 emoji 乱码 / 排查跨表 JOIN 没走索引时。

字符集utf8mb4排序规则collationemoji 乱码charsetjoin 隐式转换
paths
  • *.sql
  • *.yml
  • *.properties
  • *.xml

MySQL · 字符集统一 utf8mb4

本条只管「字符集/排序规则怎么定、为什么 JOIN 没走索引」。WHERE 单列的隐式类型转换见 ../../../lang/sql/forbidden/no-implicit-conversion.md(本条专管字符集/collation 这一类)。

规则

约定 原因
字符集 全用 utf8mb4 MySQL 的 utf8 是 3 字节阉割版,存不下 emoji / 部分中日韩生僻字(4 字节)
排序规则 团队统一一种(如 utf8mb4_0900_ai_ciutf8mb4_general_ci JOIN 两列 collation 不一致会触发隐式转换
作用范围 库 + 表 + 列 + 连接 四处都要 utf8mb4 任一处不是 utf8mb4 都可能乱码

建库建表

-- ✅ 库级默认
CREATE DATABASE app DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci;

-- ✅ 表级显式(继承库默认也行,显式更稳)
CREATE TABLE t (
  name VARCHAR(100) NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;

连接层(JDBC / 客户端)也要 utf8mb4:

jdbc:mysql://host:3306/app?characterEncoding=utf8mb4

collation 不一致 → JOIN 索引失效

-- ❌ a.code 是 utf8mb4_general_ci,b.code 是 utf8mb4_0900_ai_ci
-- JOIN 时需把一侧转换,索引失效退化全表扫
SELECT * FROM a JOIN b ON a.code = b.code;
-- ✅ 统一两表该列 collation,或建表时就一致
ALTER TABLE b MODIFY code VARCHAR(32) COLLATE utf8mb4_general_ci;

排查信号:两表各自单查都走索引,一 JOIN 就全表扫,先查 SHOW FULL COLUMNS 看两列 collation 是否一致。

自检

  • [ ] 库、表、列、连接四处是否都是 utf8mb4,没有残留 utf8(3 字节)?
  • [ ] 全库 collation 是否统一一种,避免 JOIN 隐式转换?
  • [ ] 需要存 emoji / 生僻字的字段确认是 utf8mb4?
  • [ ] JOIN 突然不走索引时,查过两列 collation 是否一致?

相关