初始化資料庫叢集時,可以設定資料庫的字串排序、字元歸類方法、數值格式、日期格式、時間格式、貨幣格式等。另外,為了支援國際化,資料庫通常會涉及到LC_COLLATE和LC_CTYPE的概念。
LC_COLLATE | String sort order |
LC_CTYPE | 字元分類 |
LC_MESSAGES | 訊息的語言 |
LC_MONETARY | 貨幣使用的格式 |
LC_NUMERIC | 數字使用的格式 |
LC_TIME | 時間日期使用的格式 |
您可以利用這些特性,按本土化需求,輸出對應的順序或者格式。本文將通過樣本介紹如何設定資料庫的本土化資訊以及如何設定輸出結果按中文的拼音順序進行排序。
PostgreSQL 支援的字元集類型
您可以參考PostgreSQL 的官方文檔查看。
查詢字元集支援的LC_COLLATE和LC_CTYPE資訊
您可以使用如下SQL查詢系統資料表pg_collation,來擷取字元集支援的LC_COLLATE和LC_CTYPE資訊。
select pg_encoding_to_char(collencoding) as encoding,collname,collcollate,collctype from pg_collation ;返回結果如下所示,encoding為空白時,表示這個collation支援所有的字元集。
encoding | collname | collcollate | collctype
------------+-----------------------+-----------------------+-----------------------
| default | |
| C | C | C
| POSIX | POSIX | POSIX
UTF8 | aa_DJ | aa_DJ.utf8 | aa_DJ.utf8
LATIN1 | aa_DJ | aa_DJ | aa_DJ
LATIN1 | aa_DJ.iso88591 | aa_DJ.iso88591 | aa_DJ.iso88591
UTF8 | aa_DJ.utf8 | aa_DJ.utf8 | aa_DJ.utf8
UTF8 | aa_ER | aa_ER | aa_ER
UTF8 | aa_ER.utf8 | aa_ER.utf8 | aa_ER.utf8
.......
EUC_CN | zh_CN | zh_CN | zh_CN
UTF8 | zh_CN | zh_CN.utf8 | zh_CN.utf8
EUC_CN | zh_CN.gb2312 | zh_CN.gb2312 | zh_CN.gb2312
UTF8 | zh_CN.utf8 | zh_CN.utf8 | zh_CN.utf8
UTF8 | zh_HK | zh_HK.utf8 | zh_HK.utf8
UTF8 | zh_HK.utf8 | zh_HK.utf8 | zh_HK.utf8
EUC_CN | zh_SG | zh_SG | zh_SG
UTF8 | zh_SG | zh_SG.utf8 | zh_SG.utf8
EUC_CN | zh_SG.gb2312 | zh_SG.gb2312 | zh_SG.gb2312
UTF8 | zh_SG.utf8 | zh_SG.utf8 | zh_SG.utf8
EUC_TW | zh_TW | zh_TW.euctw | zh_TW.euctw
UTF8 | zh_TW | zh_TW.utf8 | zh_TW.utf8
EUC_TW | zh_TW.euctw | zh_TW.euctw | zh_TW.euctw
UTF8 | zh_TW.utf8 | zh_TW.utf8 | zh_TW.utf8
UTF8 | zu_ZA | zu_ZA.utf8 | zu_ZA.utf8
LATIN1 | zu_ZA | zu_ZA | zu_ZA
LATIN1 | zu_ZA.iso88591 | zu_ZA.iso88591 | zu_ZA.iso88591
UTF8 | zu_ZA.utf8 | zu_ZA.utf8 | zu_ZA.utf8
(869 rows)設定資料庫的本土化(collate)資訊
設定欄位的本土化
前提條件
執行如下SQL命令,查詢當前資料庫的字元集(encoding)類型,並瞭解清楚與您當前資料庫字元集相容的collate。
select datname,pg_encoding_to_char(encoding) as encoding from pg_database;返回結果如下所示:
datname | encoding --------------------+----------- template1 | UTF8 template0 | UTF8 db | SQL_ASCII db1 | EUC_CN contrib_regression | UTF8 test01 | UTF8 test02 | UTF8 postgres | UTF8 (8 rows)操作步驟
在建立表時,執行如下命令,指定相容當前字元集的collate。
CREATE TABLE test1 ( a text COLLATE "de_DE", b text COLLATE "es_ES" );執行如下命令,修改列collate。
說明修改列collate時,會導致rewrite table,大表請謹慎操作。
如下樣本中
test1為表名,a為待修改列collate的列名。
alter table test1 alter a type text COLLATE "en_US";
在SQL使用本土化
使用本土化,改變order by輸出排序。命令如下:
select * from <table_name> order by <column_name> collate "C";使用本土化,改變操作符的結果。樣本如下:
命令:
select * from <table_name> where <column_name> > 'Tom' collate "C";
使用本土化索引進行排序
排序語句中的collate與索引的collate保持一致,才能使用這個索引進行排序。命令如下:
create index idxa on <table_name>(<column_name> collate "en_US"); explain select * from <table_name> order by <column_name> collate "en_US";輸出結果樣本如下:
QUERY PLAN ------------------------------------------------------------------------ Index Only Scan using idxa on <table_name> (cost=0.15..31.55 rows=1360 width=64) (1 row)
設定輸出結果按拼音排序
您可以通過如下四種方法來設定按拼音排序:
使用本土化 SQL。該方法不修改原有資料。命令如下:
select * from <table_name> order by <column_name> collate "en_US";使用本土化欄位。若已有資料,使用該方法時需要調整原有資料。命令如下:
alter table <table_name> alter <column_name> type text COLLATE "en_US";使用本土化索引以及本土化 SQL。該方法不修改原有資料。命令如下:
create index idxa on <table_name>(<column_name> collate "en_US"); explain select * from <table_name> order by <column_name> collate "en_US";輸出結果樣本如下:
QUERY PLAN ------------------------------------------------------------------------ Index Only Scan using idxa on <table_name> (cost=0.15..31.55 rows=1360 width=64) (1 row)將資料庫的collate設定為en_US,資料會將預設使用這個collate按拼音排序。命令如下:
create database test03 encoding 'UTF8' lc_collate 'en_US.utf8' lc_ctype 'en_US.utf8' template template0; \c test03 select * from (values ('Alice'),('Tom')) as a(c1) order by c1 ;輸出結果如下:
c1 -------- Alice Tom (2 rows)說明如果是中文,在設定按拼音排序時,要注意多音字。例如重慶(chongqing),在編碼時,重可能會按照zhong編碼,影響輸出。
在Greenplum中設定輸出結果按拼音排序
Greenplum不支援單列設定collate,按拼音排序有些許不同。
在Greenplum中,可以使用字元集轉換,按對應二進位排序,得到拼音排序的效果,如下面的命令所示:
select * from (values ('Alice'), ('Tom')) t(id) order by byteain(textout(convert(id,'UTF8','EUC_CN')));輸出結果如下:
id
--------
Alice
Tom
(2 rows)