MySQL 中的中文排序是一个非常重要且常见的需求。MySQL 中的中文排序规则比英文字母排序要复杂,因为中文默认是按字符的二进制编码或拼音进行排序,而有时我们需要按笔画等其他规则排序。
下面为您详细解析 MySQL 中的中文排序方法。
核心概念:字符集与排序规则
中文排序问题本质上是由 字符集 和 排序规则 决定的。
utf8mb4
支持包括中文在内的绝大多数字符)。_ci
(大小写不敏感)、_cs
(大小写敏感)、_bin
(二进制)结尾。 常见的中文排序规则
对于 utf8mb4
字符集,MySQL 提供了几种重要的中文排序规则:
| 排序规则 | 说明 | 特点 | | : | : | : | | utf8mb4_unicode_ci
| 基于 Unicode 排序算法,支持多语言。 | 默认推荐。对中文按拼音排序,兼容性好,是通用选择。 | | utf8mb4_zh_0900_as_cs
| Unicode 9.0 标准,专为中文优化。 | 按拼音排序,且区分声调。更准确,但需要 MySQL 8.0 及以上版本。 | | utf8mb4_zh_0900_as_ci
| Unicode 9.0 标准,专为中文优化。 | 按拼音排序,不区分声调。MySQL 8.0 及以上版本。 | | utf8mb4_chinese_ci
| 遗留的中文排序规则。 | 本质上也是拼音排序,但不如 unicode_ci
标准。不建议在新项目中使用。 |
特别注意: MySQL 没有内置直接按笔画排序的规则。如果需要笔画排序,需要使用自定义函数或应用程序处理。
实践操作:如何设置和查询
SHOW COLLATION WHERE Charset = 'utf8mb4' AND Collation LIKE '%zh%' OR Collation LIKE '%chinese%';
可以在创建表或修改表时,为特定字段指定排序规则。
-- 创建表时指定
CREATE TABLE user (
id INT PRIMARY KEY,
name VARCHAR(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci
);
-- 修改现有表的字段排序规则
ALTER TABLE user MODIFY name VARCHAR(100) COLLATE utf8mb4_unicode_ci;
这是最灵活的方式,无需修改表结构。
准备测试数据: 假设我们有一个 test_table
和如下数据:
CREATE TABLE test_table (chinese_word VARCHAR(10));
INSERT INTO test_table VALUES ('北京'), ('上海'), ('广州'), ('深圳'), ('杭州'), ('西安');
示例1:按拼音排序(默认且最常用)
SELECT chinese_word
FROM test_table
ORDER BY chinese_word COLLATE utf8mb4_unicode_ci;
结果: 北京, 广州, 杭州, 上海, 深圳, 西安 (按拼音首字母 B, G, H, S, S, X 排序)
示例2:按二进制排序
SELECT chinese_word
FROM test_table
ORDER BY chinese_word COLLATE utf8mb4_bin;
结果: 这种排序基于字符的二进制编码,顺序不可预测,通常不是我们想要的中文排序。
高级需求:实现按笔画排序
如前所述,MySQL 没有原生支持。但可以通过以下变通方法实现:
方法:使用自定义函数或字段
思路: 增加一个辅助列(如 stroke_count
)来存储每个汉字的笔画数,然后按这个数字列排序。
ALTER TABLE test_table ADD COLUMN stroke_count TINYINT;
-- 示例数据,笔画数需通过查询字典或程序获得
UPDATE test_table SET stroke_count = CASE
WHEN chinese_word = '北京' THEN 13 -- “北”5画 + “京”8画
WHEN chinese_word = '上海' THEN 11 -- “上”3画 + “海”8画
WHEN chinese_word = '广州' THEN 12 -- “广”3画 + “州”6画
WHEN chinese_word = '深圳' THEN 22 -- “深”11画 + “圳”11画
WHEN chinese_word = '杭州' THEN 15 -- “杭”8画 + “州”7画
WHEN chinese_word = '西安' THEN 12 -- “西”6画 + “安”6画
END;
SELECT chinese_word
FROM test_table
ORDER BY stroke_count;
结果: 上海 (11画), 广州 (12画), 西安 (12画), 北京 (13画), 杭州 (15画), 深圳 (22画)
缺点: 需要维护额外的数据,且添加新数据时比较麻烦。对于大规模数据,可以考虑编写一个将汉字转换为笔画数的自定义函数。
总结与建议
| 场景 | 推荐方案 | | : | : | | 通用中文拼音排序 | 在查询时使用 ORDER BY column_name COLLATE utf8mb4_unicode_ci
| | 需要更精确的拼音排序(区分声调) | 使用 ORDER BY column_name COLLATE utf8mb4_zh_0900_as_cs
(MySQL 8.0+) | | 按笔画数排序 | 1. 最佳方案: 在应用程序层(如Java, Python)实现排序逻辑。
2. 数据库方案: 在表中添加笔画数字段,排序时按该字段排序。 |
最佳实践:
utf8mb4
,排序规则使用 utf8mb4_unicode_ci
。COLLATE
子句临时指定。另外搭配便捷的MYSQL备份工具,可定时备份、异地备份,MYSQL导出导入。可本地连接LINUX里的MYSQL,简单便捷。可以大大地提高工作效率喔。
MySQL是精悍的瑞士军刀,Hive是强大的重工业车床:一次搞懂两大数据处理利器的本质区
MySQL处理中文排序,除了拼音还能怎么办?一文掌握拼音与笔画排序的所有奥秘
一小时速通MySQL:零基础入门到精通,看这篇就够了(下篇)
一小时速通MySQL:零基础入门到精通,看这篇就够了(上篇)
MySQL清空表数据,你用DELETE还是TRUNCATE?一文讲清两者核心差异与正确使用场景
从查询崩溃到丝滑流畅:详解MySQL性能优化的核心路径与高频实战技巧
MySQL性能优化漫谈:从金字塔法则到避坑指南,一位老DBA的架构思维与实践总结
千万级数据何去何从?一文读懂MySQL分库分表面试与工程实践的核心要点