现在的位置: 首页 > 综合 > 正文

postgresql通过拼音排序

2013年04月24日 ⁄ 综合 ⁄ 共 979字 ⁄ 字号 评论关闭

1、

通过使用一个开源的工具pgpinyinsort来实现,使用很简单,参看下README就OK了

http://code.google.com/p/pgpinyinsort/

 

2、

首选创建一个函数,把text转换为bytea

create or replace function text2bytea(text) returns bytea as
$$
   return $1;
$$ language plpgsql immutable;

然后通过convert函数进行转换
select * from table order by convert(text2bytea(column_need_to_sort_in_utf8),'utf8','gbk');

 

原因在于,对于文本字段(text, varchar, char类型的字段),PG是使用底层OS的locale相关的函数进行字符串比较的,众所周知,排序的一个重要的事情就是需要字符串比较函数(几乎所有的排序算法都涉及大于、小于、等于等过程)。而遗憾的是,因为各种原因(国家没有投入是一个重要原因),在各种OS上的locale相关的函数集(比如 stroll),对汉字的排序比较都不是很标准;也不是很正确。

怎么解决呢?从根本分析入手,就是要让PG不使用OS的locale相关的东西,这样,解法之一是 initdb 的时候,使用C做locale,这个时候PG会用strcmp,而不是stroll来比较字串大小。但是这样也不一定很好,因为strcmp有时候在某些特殊的编码的时候也会有些问题,并且,我们很多时候也需要locale,比如在中文的全文索引的时候。

那么,有什么办法让PG一定用类似memcp(1)这样的接口来比较数据么?

答案当然是有的:还记得PG有个数据类型是二进制数据类型么?它就是BYTEA,在PG中,所有的变长类型:TEXT、BYTEA、 VARCHAR等的底层结构都是一样的,但是每个类型在SQL子句中调用的OS处理函数不同,比如BYTEA就是使用memcp(1)进行排序的比较的,因此,我们可以想办法把TEXT的类型转换成BYTEA进行ORDER BY,这样就可以即使用locale,又绕开stroll的限制。

 

3、

在有的OS环境(语言与编码)以及POSTGRESQL版本中,直接使用order by col1...似乎就已经是按照拼音顺序来排序的了

抱歉!评论已关闭.