公益是一辈子的事,I'mdigoal,Justdoit.
5minuteread
能不能把在ORACLE里实现的汉字转拼音首字母的功能在PG里面实现以下。
比如股票软件,五粮液这个股,输入wly就可以出来了。
其实用到的就是汉字的拼音首字母,提高了用户体验。
在手机上打字比电脑上打字更慢,如果能实现这种类似的缩写可以大大提高用户体验,比如在搜索人名或者歌曲名,城市名时使用可以比较广泛。当然一般程序上就可以有类似的库可以调用,实现起来也比数据库效率要高。
我这里只是举个数据库实现的例子。
首先要找到汉字对应的拼音的码表,这个网上很多,我以gbk为例,共计6727个汉字.其他的编码如18030汉字更多,但是常用的GBK其实也够了.
1、汉字和拼音以及拼音首字母的对照表
createtablepinyin(hzvarchar(1),pyvarchar(6),zmvarchar(1));2、索引以及唯一约束
createindexidx_pinyin_hzonpinyin(hz);createuniqueindexidx_pinyin_hz_pyonpinyin(hz,py);--createuniqueindexidx_pinyin_hz_zmonpinyin(hz,zm);--这个可能不能唯一,例如多音字,可能首字母重复。3、未收录汉字将插入以下表
createtablenew_discover(hzvarchar(1)primarykey,pyvarchar(6),zmvarchar(1));4、码表的SQL详见附件
接下来创建字符串转拼音和拼音首字母的函数,注意有些是多音字,所以这个函数以数组的形式输出,组合了所有的多音字.
仅支持UTF8编码,因为ascii函数转超过255的码时仅支持UTF8.
如果要通用,可以把ascii的判断去掉.把ascii码表写入pinyin表即可.
5、转换函数如下
digoal=#select*fromget_py_zm('你好a长安,我很好!')as(c1text[],c2text[]);NOTICE:relation"tmp_get_py_zm"alreadyexists,skippingCONTEXT:SQLstatement"CREATETEMPORARYTABLEIFNOTEXISTStmp_get_py_zm(idint,pyvarchar(6),zmvarchar(1))ONCOMMITDELETEROWS"PL/pgSQLfunction"get_py_zm"line13atSQLstatementc1|c2-----------------------------------------------------------+---------------------------------{"nihaoachangan,wohenhao!","nihaoazhangan,wohenhao!"}|{"nhaca,whh!","nhaza,whh!"}测试无多音字的情况
digoal=#select*fromget_py_zm('爲')as(c1text[],c2text[]);NOTICE:relation"tmp_get_py_zm"alreadyexists,skippingCONTEXT:SQLstatement"CREATETEMPORARYTABLEIFNOTEXISTStmp_get_py_zm(idint,pyvarchar(6),zmvarchar(1))ONCOMMITDELETEROWS"PL/pgSQLfunction"get_py_zm"line13atSQLstatementc1|c2----+----(0rows)在码表中不存在的汉字将记录到new_discover表
digoal=#select*fromnew_discover;hz|py|zm----+----+----爲||码表中存在和不存在的汉字混合使用时也无输出
digoal=#select*fromget_py_zm('这是繁體')as(c1text[],c2text[]);NOTICE:relation"tmp_get_py_zm"alreadyexists,skippingCONTEXT:SQLstatement"CREATETEMPORARYTABLEIFNOTEXISTStmp_get_py_zm(idint,pyvarchar(6),zmvarchar(1))ONCOMMITDELETEROWS"PL/pgSQLfunction"get_py_zm"line13atSQLstatementc1|c2----+----(0rows)digoal=#select*fromnew_discover;hz|py|zm----+----+----爲||體||所以在发现new_discover中有记录后应该尽快完善到码表中.
例如
digoal=#begin;BEGINdigoal=#insertintopinyinvalues('爲','wei','w');INSERT01digoal=#insertintopinyinvalues('體','ti','t');INSERT01digoal=#deletefromnew_discoverwherehzin('體','爲');DELETE2digoal=#end;COMMIT再次执行以上查询时有返回结果
digoal=#select*fromget_py_zm('这是繁體')as(c1text[],c2text[]);NOTICE:relation"tmp_get_py_zm"alreadyexists,skippingCONTEXT:SQLstatement"CREATETEMPORARYTABLEIFNOTEXISTStmp_get_py_zm(idint,pyvarchar(6),zmvarchar(1))ONCOMMITDELETEROWS"PL/pgSQLfunction"get_py_zm"line13atSQLstatementc1|c2---------------+--------{zheshifanti}|{zsft}由于汉字在码表中不存在时,将无转换输出,所以需要改进一下.
6、改进,码表中没有的使用问号替代.
创建返回类型以及改进函数,由于函数输入参数类型一致,返回结果不一致,需要将原函数删除再创建
digoal=#select*fromget_py_zm('这是繁體,點選');c1|c2--------------------+-------------{"zheshifanti,"}|{"zsft,"}以问号代替不存在的汉字并插入new_discover表
digoal=#select*fromnew_discover;hz|py|zm----+----+----點||選||接下来测试可能使用的场景
创建包含歌手,歌曲信息的表.
createtablemusic(idserialprimarykey,songtext,singertext,songpytext[],songzmtext[],singerpytext[],singerzmtext[]);插入一条测试数据
insertintomusic(song,singer,songpy,songzm,singerpy,singerzm)select'刘德华','中国人',t1.c1,t1.c2,t2.c1,t2.c2fromget_py_zm('刘德华')t1,get_py_zm('中国人')t2;查看转码是否成功
digoal=#select*frommusic;id|song|singer|songpy|songzm|singerpy|singerzm----+--------+--------+------------+--------+---------------+----------1|刘德华|中国人|{liudehua}|{ldh}|{zhongguoren}|{zgr}(1row)插入10W条测试记录
digoal=#insertintomusic(song,singer,songpy,songzm,singerpy,singerzm)selectt.info,t.info,(t.t1).c1,(t.t1).c2,(t.t2).c1,(t.t2).c2from(selectt.info,get_py_zm(t.info)t1,get_py_zm(t.info)t2from(select'刘德华'||generate_series(1,100000)asinfo)ast)ast;创建索引,加快按字母检索的速度
digoal=#createindexidx_music_songpyonmusicusinggin(songpy);CREATEINDEXdigoal=#createindexidx_music_songzmonmusicusinggin(songzm);CREATEINDEXdigoal=#createindexidx_music_singerpyonmusicusinggin(singerpy);CREATEINDEXdigoal=#createindexidx_music_singerzmonmusicusinggin(singerzm);CREATEINDEX检索测试
digoal=#explainanalyzeselect*frommusicwheresingerzm@>array['ldh1'];QUERYPLAN-----------------------------------------------------------------------------------------------------------------------------BitmapHeapScanonmusic(cost=8.78..188.78rows=100width=176)(actualtime=0.024..0.024rows=1loops=1)RecheckCond:(singerzm@>'{ldh1}'::text[])->BitmapIndexScanonidx_music_singerzm(cost=0.00..8.75rows=100width=0)(actualtime=0.018..0.018rows=1loops=1)IndexCond:(singerzm@>'{ldh1}'::text[])Totalruntime:0.050ms(5rows)Time:0.396msdigoal=#select*frommusicwheresingerzm@>array['ldh1'];id|song|singer|songpy|songzm|singerpy|singerzm-------+---------+---------+-------------+--------+-------------+----------40947|刘德华1|刘德华1|{liudehua1}|{ldh1}|{liudehua1}|{ldh1}(1row)Time:0.308ms速度还不错.
Updated:May15,2012
17minuteread
背景云数据库PPAS版,是阿里云与EnterpriseDB公司(简称EDB)合作基于PostgreSQL高度兼容Oracle语法的数据库服务,为用户提供易于操作的迁移工具,兼容范围涵盖:PL/SQL、数据类型、高级函数、表分区等。用户可以直接在阿里云购买PPAS进行使用。如果在购买PPAS前,想试用一下...
1minuteread
2minuteread
背景使用GETSTACKEDDIAGNOSTICS捕获异常时的STACK内容。使用GETDIAGNOSTICS捕获运行过程中的状态值。GETDIAGNOSTICS捕获运行过程中的状态值Thereareseveralwaystodeterminetheeffectofacom...