mysql中文排序
时间:2010-04-20 来源:ubuntuer
之所以写这篇博客,是因为前几天才碰到了这么一个问题,以前还不知道mysql有这么一个问题。
我们的系统使用了struts+hibernate,数据库使用的是mysql,字符集统一为utf-8。
本来已经完成了,但是系统使用的时候,发现查出来的人名没有顺序,本来以为很简单,在查询的时候,指定按照name排序就可以了,岂知实际一做才发现问题:mysql数据库使用字符集为utf-8,查询出来的中文根本不是按照拼音排序的。
我的解决方案大致是:
① 在sql语句中做手脚,在查询的时候排序。
② 如果不行查询出来,在程序中,自己写个方法排序。
③ 最差的解决办法就是修改name字段,字符集使用gbk(或gb2312)
显然,第一种方法是最高效的,第三中方法是最差劲的。
不能直接在程序中改,先做几个试验:
试验一:mysql中文排序
准备工作:
在mysql中建立一个数据库,就使用test吧,建两个表test1和test2,均设置两个字段,id和name,要求是test1.name这个字段使用的字符集为UTF-8,test2.name这个字段使用的字符集为GBK,输入几条数据,记得要输入中文啊。
建表语句:
(1)test1:
CREATE TABLE `test1` (
`id` int(4) unsigned NOT NULL auto_increment,
`name` varchar(20) character set utf8 default NULL,
PRIMARY KEY (`id`)
) ;
(2)test2:
CREATE TABLE `test2` (
`id` int(4) unsigned NOT NULL auto_increment,
`name` varchar(20) character set gbk default NULL,
PRIMARY KEY (`id`)
) ;
另外修改表中字段的字符集可以使用:alter table `test1` change `name` `name` varchar (20) CHARACTER SET utf-8 NULL;
输入数据:
insert into `test1` (`id`, `name`) values('1','毛泽东');
insert into `test1` (`id`, `name`) values('2','邓小平');
insert into `test1` (`id`, `name`) values('3','江泽民');
insert into `test1` (`id`, `name`) values('4','胡锦涛');
insert into `test1` (`id`, `name`) values('5','周恩来');
insert into `test1` (`id`, `name`) values('6','温家宝');
insert into `test1` (`id`, `name`) values('7','朱镕基');
insert into `test1` (`id`, `name`) values('8','华国锋');
(缅怀一下伟人!!!呵呵。)
test2表中也一样。
进行试验:
直接使用sql语句查询:分别对test1和test2表进行如下查询:
select name from test1 order by name;
结果:
test1 |
test2 |
华国锋(h) |
邓小平(d) |
周恩来(z) |
胡锦涛(h) |
朱镕基(z) |
华国锋(h) |
毛泽东(m) |
江泽民(j) |
江泽民(j) |
毛泽东(m) |
温家宝(w) |
温家宝(w) |
胡锦涛(h) |
周恩来(z) |
邓小平(d) |
朱镕基(z) |
很明显,test1表中的数据没有按照中文拼音排序,而使用了gbk字符集的test2查询结果令人很满意。
问题:
在一个j2ee项目中,字符编码是一个很令人头痛的问题,为了和国际接轨,适应多语种,大部分项目都采用了UTF-8字符集,但是mysql中对采用UTF-8的存储中文的字段查询,却不尽如人意。
问题的解决之道:
在网上查了许久,也没有一个能够解决这个问题的方法。
这篇文章http://blog.donews.com/jenniferweng/archive/2006/08/07/991039.aspx可以称作集大成者,我也是从这里面找到的方法。
我构造的sql语句是:select name from test1 order by convert(name using gb2312) asc;
select * from core_vender_info order by convert(vender_abbrev USING gbk) COLLATE gbk_chinese_ci
在mysql中试了一下,结果很令人满意。
结论是:查询的时候,通过convert函数,把查询出来的数据使用的字符集gb2312编码就可以了,然后使用convert之后的中文排序。但是如果真的去把表中字段的字符集改成gb2312,又会涉及到很多编码的问题,页面传值啊,从数据库中存取啊,很麻烦。只要在查询的时候,指定一下字符集,并不是真的把物理字段改成gb2312,很简单。