转载地址:https://my.oschina.net/Kenyon/blog/183063

前一段时间开发人员咨询,说postgresql里面想根据一个字段做中文的拼音排序,但是不得其解

环境:
OS:CentOS 6.3
DB:PostgreSQL 9.2.4
TABLE: tbl_kenyon

场景:

postgres=# \d tbl_kenyon Table "public.tbl_kenyon"Column | Type |   Modifiers
--------+------+---------------vname  | text |--使用排序后的结果,不是很理想
postgres=# select vname from tbl_kenyon order by vname;vname
-------上海北京杭州浙江
(4 rows)

说明:
postgresql的排序除了受到数据库的编码影响外,还有一个初始化参数是locale也会影响(initdb),,通常我的选择是C,这可以让postgres数据库通过strcmp()这个函数来比较字符串,而不是strcoll()函数。这个参数可以在数据库里查看,如

postgres=# \lList of databasesName       |  Owner   | Encoding | Collate | Ctype |   Access privileges
-----------------+----------+----------+---------+-------+-----------------------dkenyon         | u_kenyon | UTF8     | C       | C     | postgres        | postgres | UTF8     | C       | C     | template0       | postgres | UTF8     | C       | C     | =c/postgres          +|          |          |         |       | postgres=CTc/postgrestemplate1       | postgres | UTF8     | C       | C     | =c/postgres          +|          |          |         |       | postgres=CTc/postgres
(6 rows)--简体中文在系统表里的支持
postgres=# select collname,collcollate,collctype,b.nspname,c.rolname as collowner
postgres-# from pg_collation a,pg_namespace b,pg_authid c
postgres-# where a.collnamespace = b.oid and a.collowner = c.oid and lower(collname) like '%zh_cn%';collname   | collcollate  |  collctype   |  nspname   | collowner
--------------+--------------+--------------+------------+-----------zh_CN        | zh_CN        | zh_CN        | pg_catalog | postgreszh_CN        | zh_CN.utf8   | zh_CN.utf8   | pg_catalog | postgreszh_CN.gb2312 | zh_CN.gb2312 | zh_CN.gb2312 | pg_catalog | postgreszh_CN.utf8   | zh_CN.utf8   | zh_CN.utf8   | pg_catalog | postgres
(4 rows)

因为初始化时选择的locale是C,所以数据库的默认排序也是C,要想字段内容按照中文拼音排序,需要将UTF8格式存储的内容转换为GBK方式。

解决办法:

1.转换字段的方式,加个convert_to前缀函数

postgres=# select vname from tbl_kenyon order by convert_to(vname,'GBK');vname -------北京杭州上海浙江
(4 rows)--convert_to函数输入参数是text形式,输出编码是bytea形式,是将字符转换为目标编码的函数,如
postgres=# select convert_to('浙江','UTF8'),('浙江','GBK');convert_to   |    row
----------------+------------\xe6b599e6b19f | (浙江,GBK)
(1 row)

2.列指定zh_cn的方式存储

postgres=# alter table tbl_kenyon add cname text collate "zh_CN";
ALTER TABLE
postgres=# \d tbl_kenyon Table "public.tbl_kenyon"Column | Type |   Modifiers
--------+------+---------------vname  | text | cname  | text | collate zh_CNpostgres=# select * from tbl_kenyon;vname | cname
-------+-------浙江  | 浙江杭州  | 杭州上海  | 上海北京  | 北京
(4 rows)postgres=# select * from tbl_kenyon order by vname;vname | cname
-------+-------上海  | 上海北京  | 北京杭州  | 杭州浙江  | 浙江
(4 rows)postgres=# select * from tbl_kenyon order by cname;vname | cname
-------+-------北京  | 北京杭州  | 杭州上海  | 上海浙江  | 浙江
(4 rows)3.查询时指定collatepostgres=# select * from tbl_kenyon order by vname collate "C";vname | cname
-------+-------上海  | 上海北京  | 北京杭州  | 杭州浙江  | 浙江
(4 rows)postgres=# select * from tbl_kenyon order by vname collate "zh_CN";vname | cname
-------+-------北京  | 北京杭州  | 杭州上海  | 上海浙江  | 浙江
(4 rows)

其他问题:

1.在用了方法一的convert_to函数转换一段时间后,开发告诉我说有异常,报错 character with byte sequence 0xc2 0xae in encoding "UTF8" has no equivalent in encoding "GBK"

Error querying database.  Cause: org.postgresql.util.PSQLException: ERROR: character with byte sequence 0xc2 0xae inencoding "UTF8" has no equivalent in encoding "GBK"

排查了一下,发现数据库里存了一些比较奇怪的字符导致的,比如Mircle® city,niwhite®town。后对该表重建了一下,用方法二解决,所以convert_to函数使用对一些奇怪的字符转换时需要注意。

2.对于多音字,仍然会产生一定的歧义,比如重庆,会按Z去排序

上述办法能满足大部分汉字的拼音排序,但仍有一些不足。比较理想的解决办法是对这类基础数据录入时就指定拼音规则,或者数据库里存一份数据的拼音字典来关联使用。

其他:
使用zh_cn存储时测试字段大小,未测试取值速度

postgres=# insert into tbl_kenyon select repeat('浙江GDOOASASHOME爱你',5000), repeat('浙江GDOOASASHOME爱你',5000) ;
INSERT 0 1
postgres=# insert into tbl_kenyon select repeat('浙江GDOOASASHOME爱你',50000), repeat('浙江GDOOASASHOME爱你',50000) ;
INSERT 0 1
postgres=# insert into tbl_kenyon select repeat('浙江GDOOASASHOME爱你',100000), repeat('浙江GDOOASASHOME爱你',100000) ;
INSERT 0 1postgres=# select pg_column_size(cname),pg_column_size(vname) from tbl_kenyon ;pg_column_size | pg_column_size
----------------+----------------1410 |           140613769 |          1376927506 |          27506
(3 rows)

存储差异并不大


补充

#高版本可能不支持,或者语法不对?
select * from  store order by storename collate 'zh_CN';

参考

http://www.yesky.com/imagesnew/software/tsql/ts_ca-co_5z55.htm

PostgreSQL的中文拼音排序(转载)相关推荐

  1. PostgreSQL的中文拼音排序

    为什么80%的码农都做不了架构师?>>>    前一段时间开发人员咨询,说postgresql里面想根据一个字段做中文的拼音排序,但是不得其解.So,Take a Loooook. ...

  2. 汉字转拼音,中文拼音排序器

    汉字转拼音 NSMutableString *ms = [[NSMutableString alloc] initWithString:@"我是中国人"]; if (CFStrin ...

  3. Java字母笔顺_Android实现中文汉字笔划(笔画)、中文拼音排序、英文排序

    一.需求描述 最近要做一个类似微信的,在登录界面选择国家地区的功能,微信有中文汉字笔画排序以及中文拼音排序等几种方式,如下所示: 微信:简体中文.拼音排序 微信:繁体中文.笔画排序 微信 英文 字母排 ...

  4. php 按汉字拼音排序,PHP数组排序关于按中文拼音排序的问题

    这天做个页面,需要将图片表里面图片的标签拉出来拆分好后去重按自然排序.结果很囧,应该排序的结果是0-9-A-z-阿-中,但是中文部分就是很乱.再找问题,结果发现自然排序是按照字符编码的顺序来排列.由于 ...

  5. 常见数据库中文拼音排序及排序对空值的处理

    常见数据库中文拼音排序及排序对空值的处理 1.中文拼音排序 2.排序对空值的处理 1.中文拼音排序 MySQL order by CONVERT (field_name USING GBK ) Pos ...

  6. Android实现中文汉字笔划(笔画)、中文拼音排序、英文排序

    发布时间:2018-11-16 技术:Android 概述 最近要做一个类似微信的,在登录界面选择国家地区的功能,微信有中文汉字笔画排序以及中文拼音排序等几种方式,如下所示: 简体中文 拼音排序;繁体 ...

  7. 前后端分别实现集合根据中文拼音排序

    java实现集合根据中文拼音排序 public static void main(String[] args){Comparator<Object> com = Collator.getI ...

  8. ElasticSearch 2.4.X实现中文拼音排序

    前言 最近接到一个需求,要求实现搜索框的搜索结果可以按照中文排序,本人灵机一动,那不很简单吗,直接按照es自带的sort功能处理下不就行了吗?两分钟的代码量,半天的喝茶时间,白赚半天的故事点,嘿嘿. ...

  9. 使用Lambda表达式对中文拼音排序(按中文字典排序)

    使用Lambda表达式对中文拼音排序(中文字典排序) 今天项目上有一个需求,要求对用户名按照拼音排序(不通过数据库端SQL操作),由于用户名为中文,所以使用常规排序并不能解决问题. package l ...

  10. js数组对象按照中文拼音排序

    今天遇到一个需求如图所示,下拉框按照中文拼音排序,而我们下拉框给的都是接口传过来的对象,所以要想排序,还是稍微需要处理一下的 话不多说,我们先看一个demo,根据这个demo,我们就能完成,我们想要的 ...

最新文章

  1. 「THUPC2018」赛艇 / Citing
  2. 多重选择函数c语言,大佬在吗,我用C写了一个去多重括号的函数,结果。。。...
  3. VS2010,C++ 制作静态库(*.lib),并使用
  4. AIX 连接IBM存储,多路径软件常用命令
  5. C#.Net工作笔记008---c# 日期时间大小比较_日期相减
  6. 【并行计算-CUDA开发】关于共享内存(shared memory)和存储体(bank)的事实和疑惑...
  7. hdu1421 搬寝室 DP
  8. 【Unity】UGUI无法修改UI元素的Pivot锚点位置
  9. cannon linux驱动下载
  10. 任玉刚【Android开发艺术探索】读后笔记四
  11. npm install 提示 path .../node_modules/node-sass command failed
  12. 除法的向上取整和向下取整
  13. 抖音同款口红机 微信口红机 在线游戏口红机开发代码 分析
  14. 机器学习分类模型评价指标详述
  15. 《宝塔面板教程5》:如何上传网站程序安装自己的网站
  16. java发送手机短信demo
  17. hackme1新手教学
  18. python 远程控制实例
  19. C#与matlab混合编程,MATLAB生成dll出现的问题,请大家一起研究一下,谢谢
  20. 0.0.0.0和255.255.255.255这两个IP地址到底有啥用?

热门文章

  1. cmd窗口ping端口的方法:telnet ip 端口
  2. PROFINET IO设备的GSD文件简介
  3. Android 小知识:使用shell screencap / screenshot命令截屏
  4. 仿直播礼物涂鸦/屏幕礼物涂鸦动画
  5. java.lang.NoSuchMethodError: org.jaxen.dom4j.DocumentNavigator.getInstance()【可能的解决办法】
  6. VMware虚拟机的Linux系统访问本地磁盘
  7. 视频通讯使用的SIP协议详解
  8. 天线远场定义_暗室静区及天线近场和远场的介绍
  9. AcWing 棋盘挑战 dsf
  10. 萤石云谷歌禁用flash_mac chrome屏蔽flash插件怎么办 mac chrome flash启用方法