PostgreSQL的中文拼音排序(转载)
转载地址: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的中文拼音排序(转载)相关推荐
- PostgreSQL的中文拼音排序
为什么80%的码农都做不了架构师?>>> 前一段时间开发人员咨询,说postgresql里面想根据一个字段做中文的拼音排序,但是不得其解.So,Take a Loooook. ...
- 汉字转拼音,中文拼音排序器
汉字转拼音 NSMutableString *ms = [[NSMutableString alloc] initWithString:@"我是中国人"]; if (CFStrin ...
- Java字母笔顺_Android实现中文汉字笔划(笔画)、中文拼音排序、英文排序
一.需求描述 最近要做一个类似微信的,在登录界面选择国家地区的功能,微信有中文汉字笔画排序以及中文拼音排序等几种方式,如下所示: 微信:简体中文.拼音排序 微信:繁体中文.笔画排序 微信 英文 字母排 ...
- php 按汉字拼音排序,PHP数组排序关于按中文拼音排序的问题
这天做个页面,需要将图片表里面图片的标签拉出来拆分好后去重按自然排序.结果很囧,应该排序的结果是0-9-A-z-阿-中,但是中文部分就是很乱.再找问题,结果发现自然排序是按照字符编码的顺序来排列.由于 ...
- 常见数据库中文拼音排序及排序对空值的处理
常见数据库中文拼音排序及排序对空值的处理 1.中文拼音排序 2.排序对空值的处理 1.中文拼音排序 MySQL order by CONVERT (field_name USING GBK ) Pos ...
- Android实现中文汉字笔划(笔画)、中文拼音排序、英文排序
发布时间:2018-11-16 技术:Android 概述 最近要做一个类似微信的,在登录界面选择国家地区的功能,微信有中文汉字笔画排序以及中文拼音排序等几种方式,如下所示: 简体中文 拼音排序;繁体 ...
- 前后端分别实现集合根据中文拼音排序
java实现集合根据中文拼音排序 public static void main(String[] args){Comparator<Object> com = Collator.getI ...
- ElasticSearch 2.4.X实现中文拼音排序
前言 最近接到一个需求,要求实现搜索框的搜索结果可以按照中文排序,本人灵机一动,那不很简单吗,直接按照es自带的sort功能处理下不就行了吗?两分钟的代码量,半天的喝茶时间,白赚半天的故事点,嘿嘿. ...
- 使用Lambda表达式对中文拼音排序(按中文字典排序)
使用Lambda表达式对中文拼音排序(中文字典排序) 今天项目上有一个需求,要求对用户名按照拼音排序(不通过数据库端SQL操作),由于用户名为中文,所以使用常规排序并不能解决问题. package l ...
- js数组对象按照中文拼音排序
今天遇到一个需求如图所示,下拉框按照中文拼音排序,而我们下拉框给的都是接口传过来的对象,所以要想排序,还是稍微需要处理一下的 话不多说,我们先看一个demo,根据这个demo,我们就能完成,我们想要的 ...
最新文章
- 「THUPC2018」赛艇 / Citing
- 多重选择函数c语言,大佬在吗,我用C写了一个去多重括号的函数,结果。。。...
- VS2010,C++ 制作静态库(*.lib),并使用
- AIX 连接IBM存储,多路径软件常用命令
- C#.Net工作笔记008---c# 日期时间大小比较_日期相减
- 【并行计算-CUDA开发】关于共享内存(shared memory)和存储体(bank)的事实和疑惑...
- hdu1421 搬寝室 DP
- 【Unity】UGUI无法修改UI元素的Pivot锚点位置
- cannon linux驱动下载
- 任玉刚【Android开发艺术探索】读后笔记四
- npm install 提示 path .../node_modules/node-sass command failed
- 除法的向上取整和向下取整
- 抖音同款口红机 微信口红机 在线游戏口红机开发代码 分析
- 机器学习分类模型评价指标详述
- 《宝塔面板教程5》:如何上传网站程序安装自己的网站
- java发送手机短信demo
- hackme1新手教学
- python 远程控制实例
- C#与matlab混合编程,MATLAB生成dll出现的问题,请大家一起研究一下,谢谢
- 0.0.0.0和255.255.255.255这两个IP地址到底有啥用?
热门文章
- cmd窗口ping端口的方法:telnet ip 端口
- PROFINET IO设备的GSD文件简介
- Android 小知识:使用shell screencap / screenshot命令截屏
- 仿直播礼物涂鸦/屏幕礼物涂鸦动画
- java.lang.NoSuchMethodError: org.jaxen.dom4j.DocumentNavigator.getInstance()【可能的解决办法】
- VMware虚拟机的Linux系统访问本地磁盘
- 视频通讯使用的SIP协议详解
- 天线远场定义_暗室静区及天线近场和远场的介绍
- AcWing 棋盘挑战 dsf
- 萤石云谷歌禁用flash_mac chrome屏蔽flash插件怎么办 mac chrome flash启用方法