全部產品
Search
文件中心

ApsaraDB RDS:設定PostgreSQL定序(Collation)

更新時間:Jun 21, 2025

初始化資料庫叢集時,可以設定資料庫的字串排序、字元歸類方法、數值格式、日期格式、時間格式、貨幣格式等。另外,為了支援國際化,資料庫通常會涉及到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)

    操作步驟

    1. 在建立表時,執行如下命令,指定相容當前字元集的collate。

      CREATE TABLE test1 (
       a text COLLATE "de_DE",
       b text COLLATE "es_ES"
      );
    2. 執行如下命令,修改列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)

參考文檔

PostgreSQL 15 Documentation — Chapter 23. Localization