MySQL中文拼音排序的问题与解决方案

 更新时间:2025年09月11日 09:19:33   作者:沃夫上校  
这篇文章主要为大家详细介绍了MySQL中文拼音排序的问题和相关解决方案,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下

问题

在做通讯录、人员列表等功能时,经常会碰到按照中文拼音排序的问题。

我们在这里可以用一个简单的例子进行说明

先创建测试数据

CREATE TABLE user (
    id INT PRIMARY KEY AUTO_INCREMENT,
    name VARCHAR(50) NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci;

INSERT INTO user (name) VALUES
('张三'),('李四'),('王五'),('赵六'),('钱七'),('孙八'),('周九'),('吴十');

下面,我们希望查出数据,并且按照中文拼音顺序排序

很简单,这样就行了

SELECT * FROM user ORDER BY name;

可是,执行后却发现,结果似乎并不符合预期

这其实是因为,MySQL 默认字符集排序:

  • utf8mb4_general_ci
  • utf8mb4_unicode_ci

这些排序是 按 Unicode 编码点排序,而不是拼音顺序。

那么,我怎么实现中文拼音排序呢?

解决办法

方法一

默认字符集排序不支持,那我不用默认字符集不就行了,看我的

SELECT * FROM user ORDER BY CONVERT(NAME USING gbk);

如果在 xml 里面使用,注意使用CDATA包裹

<select id="listUsers" resultType="User">
  SELECT id, name
  FROM user
  ORDER BY <![CDATA[CONVERT(name USING gbk)]]>
</select>

可行是可行,但是每次查询都要做编码转化,有没有更简单粗暴的方法?

方法二

有的兄弟,有的

我们可以跳过编码转化这一个步骤,添加一个冗余字段,在数据变更时写入拼音不就行了(空间换时间打法还是太强了)

我们先添加字段

ALTER TABLE user
ADD COLUMN pinyin VARCHAR(100) AFTER name;

再导入这样一个依赖

<dependency>
    <groupId>com.belerweb</groupId>
    <artifactId>pinyin4j</artifactId>
    <version>2.5.1</version>
</dependency>

再建立对应工具类

public class PinyinUtil {
    /**
     * @param chinaStr 中文字符串
     * @return 中文字符串转拼音 其它字符不变
     */
    public static String getPinyin(String chinaStr){
        HanyuPinyinOutputFormat formart = new HanyuPinyinOutputFormat();
        formart.setCaseType(HanyuPinyinCaseType.LOWERCASE);
        formart.setToneType(HanyuPinyinToneType.WITHOUT_TONE);
        formart.setVCharType(HanyuPinyinVCharType.WITH_V);
        char[] arrays = chinaStr.trim().toCharArray();
        String result = "";
        try {
            for (int i=0;i<arrays.length;i++) {
                char ti = arrays[i];
                if(Character.toString(ti).matches("[\u4e00-\u9fa5]")){ //匹配是否是中文
                    String[] temp = PinyinHelper.toHanyuPinyinStringArray(ti,formart);
                    result += temp[0];
                }else{
                    result += ti;
                }
            }
        } catch (BadHanyuPinyinOutputFormatCombination e) {
            e.printStackTrace();
        }
        
        return result;
    }
}

PinyinUtil.getPinyin()会根据中文字符串返回对应的拼音字符串

在涉及到数据变更(新增、修改、导入等场景)时,写入冗余字段就行

String pinyin = PinyinUtil.getPinyin(name);
user.setPinyin(pinyin);

我们的测试数据表在经过处理后,就变成了这样

查询时,对冗余字段排序即可

SELECT * FROM user ORDER BY pinyin;

当数据量超过 几百万条以上,方法二的优势会明显

当然,方法一不用做多余操作,直接sql搞定,也是一个优点

到此这篇关于MySQL中文拼音排序的问题与解决方案的文章就介绍到这了,更多相关MySQL中文拼音排序内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • 解析如何使用Zend Framework 连接数据库

    解析如何使用Zend Framework 连接数据库

    本篇文章是对如何使用Zend Framework 连接数据库的方法进行了详细的分析介绍,需要的朋友参考下
    2013-06-06
  • MySQL报错Expression #1 of SELECT list is not in GROUP BY clause and contains nonaggre

    MySQL报错Expression #1 of SELECT list 

    这篇文章主要介绍了MySQL报错Expression #1 of SELECT list is not in GROUP BY clause and contains nonaggre问题,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
    2024-09-09
  • MySQL索引类型Normal、Unique和Full Text的讲解

    MySQL索引类型Normal、Unique和Full Text的讲解

    今天小编就为大家分享一篇关于MySQL索引类型Normal、Unique和Full Text的讲解,小编觉得内容挺不错的,现在分享给大家,具有很好的参考价值,需要的朋友一起跟随小编来看看吧
    2019-03-03
  • MySQL安全设置图文教程

    MySQL安全设置图文教程

    MySQL安全设置,跟mssql差不多都是以普通用户权限运行mysql。其它的也需要注意下。
    2011-01-01
  • MySQL load语句详细介绍

    MySQL load语句详细介绍

    这篇文章主要介绍了MySQL load语句详细介绍,本文讲解了load的基本语法、文件的路径、配置选项、STARTING LINES选项、TERMINATED LINES选项等内容,需要的朋友可以参考下
    2014-12-12
  • MySQL数据库连接数查询、配置简单示例代码

    MySQL数据库连接数查询、配置简单示例代码

    这篇文章主要介绍了MySQL数据库连接数查询、配置的相关资料,连接数与性能密切相关,需要根据实际需求合理配置,通过设置最大连接数、使用连接池和优化应用程序连接逻辑,可以提高数据库的稳定性和性能,需要的朋友可以参考下
    2025-03-03
  • mysql where中如何判断不为空的实现

    mysql where中如何判断不为空的实现

    本文主要介绍了mysql where中如何判断不为空的实现,本文将针对这些空演示如何判断是否为空,以及如何写sql过滤,包括使用判空函数,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2022-03-03
  • MySQL InnoDB Cluster搭建安装教程

    MySQL InnoDB Cluster搭建安装教程

    这篇文章主要介绍了MySQL InnoDB Cluster搭建安装教程,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友参考下吧
    2024-01-01
  • 很全面的Mysql数据库、数据库表、数据基础操作笔记(含代码)

    很全面的Mysql数据库、数据库表、数据基础操作笔记(含代码)

    这篇文章主要为大家分享了很全面的Mysql数据库、数据库表、数据基础操作笔记,感兴趣的小伙伴们可以参考一下
    2016-04-04
  • mysql中between的用法及说明

    mysql中between的用法及说明

    这篇文章主要介绍了mysql中between的用法及说明,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2023-07-07

最新评论