为什么80%的码农都做不了架构师?>>>   

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

环境:
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.查询时指定collate

postgres=# 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 in encoding "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)

存储差异并不大

参考:
http://www.postgresql.org/docs/9.2/static/collation.html http://blog.163.com/digoal@126/blog/static/163877040201173003547236/ http://en.wikipedia.org/wiki/Collation

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

PostgreSQL的中文拼音排序相关推荐

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

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

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

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

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

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

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

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

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

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

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

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

  7. php 按汉字拼音排序,php 数组按中文拼音排序

    本篇文章给大家分享的内容是关于php数组按中文拼音排序,有着一定的参考价值,有需要的朋友可以参考一下 $str = "我们可以在浏览器中看到,当鼠标移到元素上时,元素开始向右移动,开始比较慢 ...

  8. 【我的Android进阶之旅】Android实现中文汉字笔划(笔画)排序、中文拼音排序、英文排序的国家地区选择界面

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

  9. mysql列按照中文拼音排序

    如果你的需求仅仅是要对字段进行中文拼音排序可以把要排序的列的排序规则改一下如下 ALTER TABLE `你的表`CHANGE COLUMN `列名称` `列名称` VARCHAR(50) COLLA ...

最新文章

  1. 网络编程之---广播和IP多播
  2. 大数据开发实战:数据流图及相关数据技术
  3. [react] 在React中组件的state和setState有什么区别?
  4. linux代码_Sonar代码走查的配置(linux)
  5. 输出图片任意点的像素坐标(结合IRFANVIEW使用)
  6. 李国庆深夜发“15条真相”回应:关于原生家庭、同性恋、1.3亿...
  7. ad19做直插封装 ipc_AD19的IPC封装向导使用
  8. C语言找出完数并输出
  9. 如何控制局域网网速_免费局域网监控软件如何提升控制性能 - 百科
  10. echarts地图设置label引导线
  11. EasyPlayer播放海康大华RTSP流时RTSPClient客户端连接兼容问题的解决
  12. incaseformat蠕虫病毒样本分析
  13. 威纶触摸屏485通信控制多台台达变频器程序
  14. Alsa 调试下篇:应用篇
  15. Peeking into the Future: Predicting Future Person Activities and Locations in Videos 翻译
  16. 微信返利机器人开发制作
  17. 前端切图案例课程一则-姜威-专题视频课程
  18. Webots 机器人仿真平台(一) 系统安装
  19. 人工智能中的图灵测试
  20. Android View(一)——View的基础知识

热门文章

  1. 用python编程输入三角形的三条边判断是否构成三角形_vb三角形编程输入三条边,判断能否构成三角形.看我的编程是否有问题,...
  2. java 直播_一对一直播源码开发过程中区分Java和PHP的重要性
  3. 区块链研究生专业_滁州区块链平台技术开发专业软件公司
  4. jdba访问mysql_Java中JDBC操作数据库的步骤
  5. 一体机服务器性能,一体机的服务器
  6. 哈工大计算机考研 跨考,09哈工大计算机考研复试之我的经历_跨考网
  7. 18 个惊人的 GitHub 仓库
  8. hyper-v ubuntu 图形界面不流畅_ubuntu简单美化教程
  9. c语言读取txt第二行数值,c语言读取文件的第二行
  10. xp和linux的引导文件,Linux与XP双系统中grub引导配置笔记