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

 更新时间:2026年01月24日 09:13:15   作者:IT枫斗者  
MySQL提供了多种字符集和排序规则选择,其中字符集设置和数据存储以及客户端与MySQL实例的交互相关,这篇文章主要介绍了MySQL字符集与排序规则utf8mb4、utf8mb3、collation选型与避坑总结的相关资料,需要的朋友可以参考下

前言

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

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

  • 字符集(Character Set):决定“字符怎么编码存储”(能不能存 emoji、本质占多少字节)
  • 排序规则(Collation):决定“字符怎么比较/排序”(是否大小写敏感、是否忽略重音、中文排序规则)

举个最直观的:

  • utf8mb4 决定你能不能存 😊
  • utf8mb4_0900_ai_ci 决定 'A' 是否等于 'a'ée 是否算相等、排序是否更准确

1. DEFAULT CHARACTER SET 是否必须写?

1.1 结论(按场景给)

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

1.2 DataGrip 为什么默认不写?

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

  • character_set_server = utf8mb4
  • collation_server = utf8mb4_0900_ai_ci

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

-- 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 核心结论

  • utf8mb4 = 真正的 UTF-8(完整 Unicode,支持 emoji)
  • utf8mb3(或 utf8)= MySQL 历史遗留的 3 字节 UTF-8,不完整

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 ('张三😊');

常见错误类似:

  • Incorrect string value: '\xF0\x9F...' for column ...

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

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

  • 你永远无法保证用户输入、第三方接口、运营文案、复制粘贴内容不出现 4 字节字符
  • 一旦出现,轻则插入失败,重则数据截断、业务异常、日志污染

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

排序规则名字拆开看:

  • utf8mb4_0900_ai_ci
    • 0900:Unicode 9.0
    • ai:accent-insensitive(忽略重音)
    • ci:case-insensitive(不区分大小写)

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

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

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

  • Unicode 9.0,规则更新更全
  • 比旧版 unicode_ci 更准确
  • 性能通常更好(实现更现代)

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

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

  • 规则更旧(非 9.0)
  • 通常也够用,但不是最优

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

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

  • A ≠ a
  • 比较按字节序(“最严格”)

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 唯一索引长度问题(老版本)

  • utf8mb4 下 VARCHAR(255) 最坏是 255 * 4 = 1020 bytes
  • MySQL 5.6/早期 5.7 可能受限(767 bytes 等历史限制)
  • MySQL 8 大多无需担心,但老环境可能要:
    • VARCHAR(191)
    • 或用前缀索引

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

表现:

  • join/union 报错:Illegal mix of collations
  • 比较结果异常、排序不一致
    解决:
  • 统一库 → 表 → 字段层级的默认值
  • 迁移时用脚本批量检查并修正

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

  • utf8mb4_0900_ai_ci 下:Tomtom 认为相等
  • 如果账号体系需要区分大小写(少见,但存在),要用 _bin 或特定 _cs

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 是唯一正确选择
  • utf8/utf8mb3 是历史遗留
  • MySQL 8 默认:utf8mb4_0900_ai_ci
  • 要区分大小写:用 utf8mb4_bin

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

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

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

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

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

您可能感兴趣的文章:

相关文章

  • Windows下重启MySQL服务时报错:服务名无效的解决方法

    Windows下重启MySQL服务时报错:服务名无效的解决方法

    这篇文章主要介绍了Windows下重启MySQL服务时报错:服务名无效的解决方法,文中通过代码示例讲解的非常详细,对大家的学习或工作有一定的帮助,需要的朋友可以参考下
    2024-12-12
  • 设置MySQL自动增长从某个指定的数开始方法

    设置MySQL自动增长从某个指定的数开始方法

    下面小编就为大家带来一篇设置MySQL自动增长从某个指定的数开始方法。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2017-01-01
  • mysql数据库操作_高手进阶常用的sql命令语句大全

    mysql数据库操作_高手进阶常用的sql命令语句大全

    mysql数据库操作sql命令语句大全:三表连表查询、更新时批量替换字段部分字符、判断某一张表是否存在、自动增长恢复从1开始、查询重复记录、更新时字段值等于原值加上一个字符串、更新某字段为随机值、复制表数据到另一个表、创建表时拷贝其他表的数据和结构...
    2022-11-11
  • textarea标签(存取数据库mysql)的换行方法

    textarea标签(存取数据库mysql)的换行方法

    textarea标签本身不识别换行功能,回车换行用的是\n换行符,输入时的确有换行的效果,但是html渲染或者保存数据库mysql时就只是一个空格了,这时就需要利用换行符\n和br标签的转换进行处理
    2023-09-09
  • SQL实现时间序列错位还原案列

    SQL实现时间序列错位还原案列

    这篇文章小编主要向大家介绍的是时间序列错位还原之SQL实现案例详解的相关资料,需要的小伙伴可以参考下面文章的具体内容
    2021-09-09
  • centos下mysql主从同步快速设置步骤分享

    centos下mysql主从同步快速设置步骤分享

    记录一个比较简便的mysql的主从同步设置步骤,方便日后使用。
    2012-06-06
  • 详解Mysql 30条军规

    详解Mysql 30条军规

    这篇文章主要介绍了详解Mysql 30条军规,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2019-08-08
  • mysql幻读详解实例以及解决办法

    mysql幻读详解实例以及解决办法

    MySQL中的幻读只有在读的时候才会发生,读这里特指SELECT操作,下面这篇文章主要给大家介绍了关于mysql幻读详解实例以及解决办法的相关资料,文中通过图文介绍的非常详细,需要的朋友可以参考下
    2022-06-06
  • MySql 错误Incorrect string value for column

    MySql 错误Incorrect string value for column

    能使用中文进行搜索,但是insert into 中文是可以的。我的数据库和数据表中所有的charset都是设置的utf8。
    2010-12-12
  • MySQL出现SQL Error (2013)连接错误的解决方法

    MySQL出现SQL Error (2013)连接错误的解决方法

    这篇文章主要介绍了MySQL出现SQL Error (2013)连接错误的解决方法,2013错误主要还是在于用户的授权问题,需要的朋友可以参考下
    2016-06-06

最新评论