前几天,我在建数据库的时候,同事刚好在我旁边,他问我:"你建库一般用什么排序规则,怎么感觉都一样啊!"。
本来我还想装一下的,可发现我越讲越不对,赶紧去搜了一下相关知识,这可终于整明白了。
下面给大家分享一下。
什么是排序规则(Collation)?
简单说:排序规则决定了 MySQL 怎么"看"字符串。
比如:
- 它认为
'A'和'a'是一样的吗? - 它觉得
'é'和'e'要不要区分? - 中文字符按什么顺序排?
Collation(排序规则) 就是解决这些问题的。
排序规则长什么样?
MySQL 的排序规则名字通常像这样:
utf8mb4_0900_ai_ci
utf8mb4_general_ci
utf8mb4_bin
如下图:

我们拆开来看:
| 部分 | 含义 |
|---|---|
utf8mb4 |
字符集(支持 emoji、中文、英文等所有 Unicode 字符) |
0900 |
基于 Unicode 9.0.0 标准(MySQL 8.0+ 新特性) |
ai / as |
Accent Insensitive(不区分重音) / Accent Sensitive(区分重音) |
ci / cs |
Case Insensitive(不区分大小写) / Case Sensitive(区分大小写) |
bin |
Binary(二进制比较,最严格) |
举个栗子:不同排序规则的区别
我们创建三个表,分别用不同的排序规则,看看效果:
场景1:大小写敏感吗?
sql
-- 表1:使用 utf8mb4_0900_ai_ci(默认,不区分大小写)
CREATE TABLE users_ci (
name VARCHAR(50)
) COLLATE utf8mb4_0900_ai_ci;
INSERT INTO users_ci VALUES ('Alice'), ('alice');
-- 查询
SELECT * FROM users_ci WHERE name = 'ALICE';
-- 结果:返回 Alice 和 alice(因为不区分大小写)
sql
-- 表2:使用 utf8mb4_bin(区分大小写)
CREATE TABLE users_bin (
name VARCHAR(50)
) COLLATE utf8mb4_bin;
INSERT INTO users_bin VALUES ('Alice'), ('alice');
SELECT * FROM users_bin WHERE name = 'ALICE';
-- 结果:空!因为 'ALICE' ≠ 'Alice' ≠ 'alice'
结论 :_ci 不区分大小写,_bin 区分。
场景2:重音符号要不要管?
比如法语中的 café 和 cafe。
- 在
_ai(Accent Insensitive)规则下:café = cafe - 在
_as或_bin规则下:café ≠ cafe
MySQL 8.0+ 支持更精细的控制,比如:
sql
utf8mb4_0900_as_cs -- 区分大小写 + 区分重音
utf8mb4_0900_ai_ci -- 不区分大小写 + 不区分重音(默认)
场景3:中文排序乱序?
如果你用 utf8mb4_general_ci 排中文,可能会发现:
sql
SELECT name FROM users ORDER BY name;
-- 结果:张三、李四、王五......顺序看起来"不对"
这是因为 general_ci 是一种简化的排序算法,它为了速度牺牲了准确性。
正确做法 :用 utf8mb4_unicode_ci 或更好的 utf8mb4_0900_ai_ci(MySQL 8.0 默认),它们基于 Unicode 标准,对中文、日文、韩文等支持更好。
主要区别维度
1. 大小写敏感性(Case Sensitivity)
- _ci :Case Insensitive(不区分大小写)
- 例如:
utf8_general_ci中'A' = 'a'
- 例如:
- _cs 或 _bin :Case Sensitive(区分大小写)
utf8_bin或utf8mb4_0900_cs中'A' ≠ 'a'
注意:_cs(Case Sensitive)在旧版本中较少见,MySQL 8.0 引入了更标准的命名如 utf8mb4_0900_cs。
2. 重音符号敏感性(Accent Sensitivity)
- _ai:Accent Insensitive(不区分重音)
- _as:Accent Sensitive(区分重音)
在 MySQL 8.0+ 中,部分排序规则支持 _as/_ai,例如 utf8mb4_0900_as_cs 表示既区分大小写又区分重音。
3. 二进制排序(Binary Collation)
- 以
_bin结尾(如utf8mb4_bin) - 按照字符的二进制值(字节值)进行比较,严格区分大小写、重音、编码顺序
- 不使用语言规则,速度较快但不符合人类语言习惯
4. 语言/区域特定排序
某些排序规则针对特定语言优化:
utf8mb4_spanish_ci:西班牙语排序(如 ñ 排在 n 之后)utf8mb4_german2_ci:德语电话簿排序规则utf8mb4_ja_0900_as_cs:日语排序(需 MySQL 8.0+)
5. Unicode 版本差异(MySQL 8.0+)
MySQL 8.0 默认使用基于 Unicode 9.0 的排序规则(如 utf8mb4_0900_ai_ci):
- 更准确的多语言支持
- 更好的性能(相比旧的
utf8mb4_general_ci) 0900表示基于 Unicode 9.0.0
对比:
utf8mb4_general_ci:旧版,速度快但排序不准确(如认为'ö' = 'o')utf8mb4_unicode_ci:基于 Unicode 4.0,较准确utf8mb4_0900_ai_ci:MySQL 8.0 默认,基于 Unicode 9.0,更准确高效
常见排序规则对比示例
| 排序规则 | 大小写敏感 | 重音敏感 | 说明 |
|---|---|---|---|
utf8mb4_general_ci |
否 | 否 | 旧版通用,速度快但不准 |
utf8mb4_unicode_ci |
否 | 否 | 基于 Unicode 4.0,较准确 |
utf8mb4_0900_ai_ci |
否 | 否 | MySQL 8.0 默认,基于 Unicode 9.0 |
utf8mb4_0900_as_cs |
是 | 是 | 区分大小写和重音 |
utf8mb4_bin |
是 | 是 | 二进制比较,最快但最"机械" |
如何查看可用排序规则?
sql
SHOW COLLATION LIKE 'utf8mb4%';
如何设置排序规则?
数据库级:
sql
CREATE DATABASE db_name CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci;
表级:
sql
CREATE TABLE t (name VARCHAR(100)) COLLATE utf8mb4_bin;
列级:
sql
name VARCHAR(100) COLLATE utf8mb4_0900_as_cs
查询时临时指定:
sql
SELECT * FROM t ORDER BY name COLLATE utf8mb4_bin;
实际建议
- 一般应用 :使用
utf8mb4_0900_ai_ci(MySQL 8.0+)或utf8mb4_unicode_ci(旧版本) - 需要区分大小写 :用
utf8mb4_0900_as_cs或utf8mb4_bin - 性能敏感且无需语言规则 :用
_bin - 避免使用
utf8mb4_general_ci(除非兼容旧系统),因其排序逻辑不准确
总结
- 排序规则 = 字符串的"比较规则"
_ci= 不区分大小写,_cs/_bin= 区分- MySQL 8.0 默认的
utf8mb4_0900_ai_ci是目前最推荐的选择 - 中文、多语言项目不要用
general_ci,它已经过时了 - 用户名、密码等关键字段,建议用区分大小写的规则
本文首发于公众号:程序员刘大华,专注分享前后端开发的实战笔记。关注我,少走弯路,一起进步!
📌往期精彩
《这 5 个冷门 HTML 标签,让我直接删了100 行 JS 代码》