Mysql

关注公众号 jb51net

关闭
首页 > 数据库 > Mysql > MySQL utf8mb4、utf8mb3、collation

MySQL字符集与排序规则utf8mb4、utf8mb3、collation选型与避坑总结(可直接当团队规范)

作者:IT枫斗者

MySQL提供了多种字符集和排序规则选择,其中字符集设置和数据存储以及客户端与MySQL实例的交互相关,这篇文章主要介绍了MySQL字符集与排序规则utf8mb4、utf8mb3、collation选型与避坑总结的相关资料,需要的朋友可以参考下

前言

一句话定调:新项目永远选 utf8mb4 + utf8mb4_0900_ai_ci
绝大多数“中文乱码/emoji 报错/唯一索引异常/大小写不一致”的锅,最后都能追到:字符集/排序规则没统一

0. 先搞清两个概念:字符集 vs 排序规则

举个最直观的:

1. DEFAULT CHARACTER SET 是否必须写?

1.1 结论(按场景给)

场景是否必须写说明
本地学习 / 临时库(MySQL 8.x 默认 utf8mb4)可不写省事,跟 DataGrip 一样用 server 默认
团队项目 / 需要可复现 SQL建议写固定环境,避免“换机器就炸”
生产环境 / 多环境部署(含 5.7/云厂商)必须写防止默认值漂移导致隐蔽数据问题

1.2 DataGrip 为什么默认不写?

因为它遵循“不写 = 用服务器默认”。
MySQL 8.x 常见默认:

因此下面两句在“默认未被你改过”的前提下等价

-- DataGrip 默认:不写
CREATE DATABASE app_db;

-- 显式写:更可控
CREATE DATABASE app_db
  DEFAULT CHARACTER SET utf8mb4
  COLLATE utf8mb4_0900_ai_ci;

1.3 怎么确认你机器/线上到底默认是什么?

SHOW VARIABLES LIKE 'character_set_server';
SHOW VARIABLES LIKE 'collation_server';

SHOW VARIABLES LIKE 'character_set_%';
SHOW VARIABLES LIKE 'collation_%';

✅ 建议把“线上默认值截图/记录”写进运维文档,否则迟早有人踩坑。

2. utf8mb3 vs utf8mb4:别再被utf8这个名字骗了

2.1 核心结论

MySQL 里 utf8 实际上长期等价于 utf8mb3(只支持最多 3 字节),这就是最大误导点。

2.2 对比表

特性utf8mb3(utf8)utf8mb4(推荐)
最大字节34
emoji❌ 不支持✅ 支持
Unicode 完整性❌ 不完整✅ 完整
MySQL 8.x 状态Deprecated(废弃趋势)✅ 默认推荐

2.3 最典型的报错

-- 在 utf8mb3/utf8 表里插入 emoji 往往会失败
INSERT INTO user(username) VALUES ('张三😊');

常见错误类似:

2.4 为什么“新项目用 utf8mb3 = 技术债”?

因为这不是“是否需要 emoji”的问题:

3. 排序规则(Collation)怎么选:0900_ai_ci vs unicode_ci vs bin

排序规则名字拆开看:

3.1 常见三种排序规则的定位

A)utf8mb4_0900_ai_ci(MySQL 8.x 推荐默认)

✅ 适合:绝大多数业务表、用户输入、通用字符串
特点:

B)utf8mb4_unicode_ci(兼容旧项目/5.7 常用)

✅ 适合:历史系统已用该排序规则,或需兼容 MySQL 5.7
特点:

C)utf8mb4_bin(严格区分大小写/二进制比较)

✅ 适合:密码 hash、token、大小写敏感账号、签名、验证码、唯一标识
特点:

3.2 重点后缀:_ci / _cs / _bin

后缀含义示例
_ci不区分大小写Tom = tom
_cs区分大小写(某些 collation 有)Tom ≠ tom
_bin二进制比较,严格区分Tom ≠ tom

⚠️ 业务最容易踩的坑:用户名/邮箱用 _ci,你以为 Tomtom 是两个人,但数据库认为相等,唯一索引直接冲突。

4. 实战建议:怎么给“库/表/字段”落地标准?

4.1 新项目(MySQL 8.x)标准建库模板(推荐)

CREATE DATABASE app_db
  DEFAULT CHARACTER SET utf8mb4
  COLLATE utf8mb4_0900_ai_ci;

4.2 兼容 MySQL 5.7(或老项目迁移)模板

CREATE DATABASE app_db
  DEFAULT CHARACTER SET utf8mb4
  COLLATE utf8mb4_unicode_ci;

4.3 建表时建议也显式写(团队协作更稳)

CREATE TABLE user (
  id BIGINT PRIMARY KEY AUTO_INCREMENT,
  username VARCHAR(50) NOT NULL
) ENGINE=InnoDB
  DEFAULT CHARSET=utf8mb4
  COLLATE=utf8mb4_0900_ai_ci;

4.4 字段级别什么时候需要单独设置?

一般不需要,继承库/表的默认即可。

只有在“局部需要强规则”时才做字段级设置:

-- token/密钥/大小写敏感字段
token VARCHAR(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin NOT NULL;

5. 常见坑位提醒(面试/线上事故高频)

5.1 唯一索引长度问题(老版本)

5.2 “同一库里表的 collation 不一致”导致的隐蔽 bug

表现:

5.3 大小写不敏感导致唯一索引误伤

6. 快速参考(直接贴到文档里)

6.1 选型速查表

场景字符集排序规则备注
新项目(MySQL 8)utf8mb4utf8mb4_0900_ai_ci⭐ 默认推荐
老项目兼容(MySQL 5.7)utf8mb4utf8mb4_unicode_ci兼容优先
需要严格大小写敏感utf8mb4utf8mb4_bintoken/签名/账号等
❌ 不要用utf8 / utf8mb3-历史遗留

6.2 常用排查命令

-- 服务器默认
SHOW VARIABLES LIKE 'character_set_server';
SHOW VARIABLES LIKE 'collation_server';

-- 数据库定义
SHOW CREATE DATABASE app_db;

-- 表定义
SHOW CREATE TABLE user;

-- 当前连接字符集(很重要,决定客户端发给服务端怎么编码)
SHOW VARIABLES LIKE 'character_set_client';
SHOW VARIABLES LIKE 'character_set_connection';
SHOW VARIABLES LIKE 'character_set_results';

7. 记忆口诀(文章收尾加分)

最后一段总结(可直接当结尾)

跨环境最怕的不是“你写错”,而是“你没写”,让默认值悄悄决定了线上行为。

所以:本地可以省略,项目/生产必须显式指定

只要把 utf8mb4 + 合理 collation 统一了,乱码、emoji 报错、比较排序异常、mix collations 等问题会少一大半。

到此这篇关于MySQL字符集与排序规则utf8mb4、utf8mb3、collation选型与避坑总结的文章就介绍到这了,更多相关MySQL utf8mb4、utf8mb3、collation内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

您可能感兴趣的文章:
阅读全文