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 没有内置直接按笔画排序的规则。如果需要笔画排序,需要使用自定义函数或应用程序处理。
实践操作:如何设置和查询
1. 查看数据库支持的全部中文排序规则
```sql
SHOW COLLATION WHERE Charset = 'utf8mb4' AND Collation LIKE '%zh%' OR Collation LIKE '%chinese%';
```
2. 在表/列级别指定排序规则
可以在创建表或修改表时,为特定字段指定排序规则。
```sql
-- 创建表时指定
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;
```
3. 在 SQL 查询时临时指定排序规则(最常用)
这是最灵活的方式,无需修改表结构。
准备测试数据:
假设我们有一个 `test_table` 和如下数据:
```sql
CREATE TABLE test_table (chinese_word VARCHAR(10));
INSERT INTO test_table VALUES ('北京'), ('上海'), ('广州'), ('深圳'), ('杭州'), ('西安');
```
示例1:按拼音排序(默认且最常用)
```sql
SELECT chinese_word
FROM test_table
ORDER BY chinese_word COLLATE utf8mb4_unicode_ci;
```
结果: 北京, 广州, 杭州, 上海, 深圳, 西安
*(按拼音首字母 B, G, H, S, S, X 排序)*
示例2:按二进制排序
```sql
SELECT chinese_word
FROM test_table
ORDER BY chinese_word COLLATE utf8mb4_bin;
```
结果: 这种排序基于字符的二进制编码,顺序不可预测,通常不是我们想要的中文排序。
高级需求:实现按笔画排序
如前所述,MySQL 没有原生支持。但可以通过以下变通方法实现:
方法:使用自定义函数或字段
思路: 增加一个辅助列(如 `stroke_count`)来存储每个汉字的笔画数,然后按这个数字列排序。
1. 修改表结构,添加笔画数列
```sql
ALTER TABLE test_table ADD COLUMN stroke_count TINYINT;
```
2. 为数据设置笔画数(需要外部工具或手动填写)
```sql
-- 示例数据,笔画数需通过查询字典或程序获得
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;
```
3. 按笔画数列排序
```sql
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)实现排序逻辑。<br>2. 数据库方案: 在表中添加笔画数字段,排序时按该字段排序。 |
最佳实践:
1. 创建数据库和表时,字符集统一使用 `utf8mb4`,排序规则使用 `utf8mb4_unicode_ci`。
2. 在具体的查询中,如果默认排序不满足要求,再使用 `COLLATE` 子句临时指定。
3. 对于笔画排序这种复杂需求,除非数据库压力很大,否则优先考虑在应用层处理,这样更灵活、更易于维护。
另外搭配便捷的MYSQL备份工具,可定时备份、异地备份,MYSQL导出导入。可本地连接LINUX里的MYSQL,简单便捷。可以大大地提高工作效率喔。
清空MySQL数据表千万别用错!DELETE和TRUNCATE这个区别可能导致重大事故
你的MySQL中文排序一团糟?记住这几点,轻松实现准确拼音排序!
企业级数据架构:MySQL递归查询在组织权限树中的高级应用实践
企业级MySQL时间管理实践:高并发场景下的性能优化与时区解决方案
【保姆级教程】MySQL主从复制最全配置指南,含监控脚本和故障处理
企业级MySQL高效查询方案:字符串匹配性能优化与全文检索最佳实践
运维基础技能:Linux服务器MySQL版本信息核查的标准化流程
企业级Docker MySQL部署方案:生产环境配置、数据持久化与网络隔离实践
企业级MySQL权限审计指南:从基础查询到安全合规的最佳实践