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内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • MySQL8.0.23安装超详细教程

    MySQL8.0.23安装超详细教程

    这篇文章主要介绍了MySQL8.0.23安装超详细教程,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2021-01-01
  • Mysql的root账户密码忘记了怎么解决(百分百教会你重置!)

    Mysql的root账户密码忘记了怎么解决(百分百教会你重置!)

    mysql是常用的数据库,很多程序员在使用的过程中会出现root用户密码忘记的事情,这篇文章主要给大家介绍了关于Mysql的root账户密码忘记了该怎么解决的相关资料,文中介绍的方法百分百教会你如何重置,需要的朋友可以参考下
    2024-05-05
  • MySQL慢查询工具的使用小结

    MySQL慢查询工具的使用小结

    使用MySQL的慢查询工具可以帮助开发者识别和优化性能不佳的SQL查询,本文就来介绍一下MySQL的慢查询工具,具有一定的参考价值,感兴趣的可以了解一下
    2025-08-08
  • mysql查询FIND_IN_SET REGEXP实践示例

    mysql查询FIND_IN_SET REGEXP实践示例

    这篇文章主要为大家介绍了mysql查询FIND_IN_SET REGEXP实践示例详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2023-05-05
  • MySQL数据库操作DML 插入数据,删除数据,更新数据

    MySQL数据库操作DML 插入数据,删除数据,更新数据

    这篇文章主要介绍了MySQL数据库操作DML插入数据,删除数据,更新数据,DML是指数据操作语言,英文全称是Data Manipulation Language,用来对数据库中表的数据记录进行更新
    2022-07-07
  • MySQLMerge存储引擎

    MySQLMerge存储引擎

    MERGE存储引擎把一组MyISAM数据表当做一个逻辑单元来对待,让我们可以同时对他们进行查询。本文给大家介绍MySQLMerge存储引擎,需要的朋友参考下吧
    2016-03-03
  • Mysql5.7.11在windows10上的安装与配置(解压版)

    Mysql5.7.11在windows10上的安装与配置(解压版)

    本文分为三大步给大家介绍Mysql5.7.11解压版在windows10上的安装与配置,另外还给大家带来了mysql5.7.11服务无法启动,错误代码3534的解决方案,非常不错,有需要的朋友参考下
    2016-08-08
  • win32安装配置非安装版的MySQL

    win32安装配置非安装版的MySQL

    当前非安装版是从MySQL.com下载来的v5.1.40;下载下来的是一个ZIP压缩包,解压到C:\MySQL5.1.40目录,接下来,设置系统环境变量,好在CMD命令行下使用MySQL。
    2010-02-02
  • MySql服务未知原因消失解决方法

    MySql服务未知原因消失解决方法

    这篇文章主要介绍了MySql服务未知原因消失解决方法的相关资料,需要的朋友可以参考下
    2017-04-04
  • MySQL中LIKE BINARY和LIKE模糊查询实例代码

    MySQL中LIKE BINARY和LIKE模糊查询实例代码

    通常在实际应用中,会涉及到模糊查询的需求,下面这篇文章主要给大家介绍了关于MySQL中LIKE BINARY和LIKE模糊查询的相关资料,文中通过实例代码介绍的非常详细,需要的朋友可以参考下
    2022-11-11

最新评论