23.3. 字元集支援

但是,一個重要的限制是每個資料庫的字元集必須與資料庫的 LC_CTYPE(字元分類)和 LC_COLLATE(字串排序順序)語言環境設定相容。對於 C 或 POSIX 語言環境,允許使用任何字元集,但對於其他 libc 提供的語言環境,只有一個字元集可以正常工作。(但在 Windows 上,UTF-8 編碼可以與任何語言環境一起使用。)如果您配置了 ICU 支援,ICU 提供的語言環境可以與大多數但不是所有伺服器端編碼一起使用。

Table 23.1 顯示了可在 PostgreSQL 中使用的字元集。

Table 23.1. PostgreSQL Character Sets

並非所有用戶端 API 都支援所有列出的字元集。例如,PostgreSQL JDBC 驅動程式就不支援 MULE_INTERNAL,LATIN6,LATIN8 和 LATIN10。

SQL_ASCII 設定與其他設定的行為大不相同。當伺服器字元集是 SQL_ASCII 時,伺服器根據 ASCII 標準解譯位元組值 0-127,而位元組值 128-255 作為未解譯的字元。當設定為 SQL_ASCII 時,不會進行編碼轉換。因此,這個設定並不是使用特定編碼的宣告,而是對編碼的未知宣告。在大多數情況下,如果您使用任何非 ASCII 資料,使用 SQL_ASCII 設定是不明智的,因為 PostgreSQL 將無法透過轉換或驗證非 ASCII 字元來幫助您。

initdb 定義 PostgreSQL 叢集的預設字元集(編碼)。例如,

將預設字元集設定為 EUC_JP(日本語的延伸 Unix 代碼)。如果您喜歡更長的選項字串,則可以使用 —encoding 而不是 -E。如果使用 -E 或 —encoding 選項,initdb 將嘗試根據指定的或預設的語言環境決定要使用的相對應編碼。

您可以在資料庫建立時指定非預設編碼,前提是該編碼與所選語言環境相容:

  1. createdb -E EUC_KR -T template0 --lc-collate=ko_KR.euckr --lc-ctype=ko_KR.euckr korean

    請注意,上述指令指定複製 template0 資料庫。複製任何其他資料庫時,無法更改原資料庫的編碼和語言環境設定,因為這可能會導致資料損壞。有關更多訊息,請參閱第 22.3 節

    資料庫的編碼儲存在系統目錄 pg_database 中。您可以使用 psql -l 選項或 \l 指令查看。

    注意
    在大多數現代作業系統上,PostgreSQL 可以確定 LC_CTYPE 設定所隱含的字元集,並強制只使用相符合的資料庫編碼。在較舊的系統上,您有責任確保使用所選區域設定所需的編碼。此區域中的錯誤可能會導致與區域設定相關操作(如排序)的奇怪行為。

    即使 LC_CTYPE 不是 C 或 POSIX,PostgreSQL 也允許超級使用者使用 SQL_ASCII 編碼建立資料庫。如上所述,SQL_ASCII 不強制儲存在資料庫中的資料具有任何特定編碼,因此這種選擇會帶來相依於語言環境的錯誤行為風險。不推薦使用這種設定組合,有一天可能會被禁止使用。

    PostgreSQL 支援伺服器和用戶端之間針對某些字元集組合的自動字元集轉換。轉換訊息儲存在 pg_conversion 系統目錄中。PostgreSQL 帶有一些預先定義的轉換,如 所示。您可以使用 SQL 指令 CREATE CONVERSION 建立新的轉換。

    Table 23.2. Client/Server Character Set Conversions

    Server Character Set Available Client Character Sets
    BIG5 not supported as a server encoding
    EUC_CN EUC_CN, MULE_INTERNAL, UTF8
    EUC_JP EUC_JP, MULE_INTERNAL, SJIS, UTF8
    EUC_KR EUC_KR, MULE_INTERNAL, UTF8
    EUC_TW EUC_TW, BIG5, MULE_INTERNAL, UTF8
    GB18030 not supported as a server encoding
    GBK not supported as a server encoding
    ISO_8859_5 ISO_8859_5, KOI8R, MULE_INTERNAL, UTF8, WIN866, WIN1251
    ISO_8859_6 ISO_8859_6, UTF8
    ISO_8859_7 ISO_8859_7, UTF8
    ISO_8859_8 ISO_8859_8, UTF8
    JOHAB JOHAB, UTF8
    KOI8R KOI8R, ISO_8859_5, MULE_INTERNAL, UTF8, WIN866, WIN1251
    KOI8U KOI8U, UTF8
    LATIN1 LATIN1, MULE_INTERNAL, UTF8
    LATIN2 LATIN2, MULE_INTERNAL, UTF8, WIN1250
    LATIN3 LATIN3, MULE_INTERNAL, UTF8
    LATIN4 LATIN4, MULE_INTERNAL, UTF8
    LATIN5 LATIN5, UTF8
    LATIN6, UTF8
    LATIN7 LATIN7, UTF8
    LATIN8 LATIN8, UTF8
    LATIN9 LATIN9, UTF8
    LATIN10 LATIN10, UTF8
    MULE_INTERNAL MULE_INTERNAL, BIG5, EUC_CN, EUC_JP, EUC_KR, EUC_TW, ISO_8859_5, KOI8R, LATIN1 to LATIN4, SJIS, WIN866, WIN1250, WIN1251
    SJIS not supported as a server encoding
    SQL_ASCII any (no conversion will be performed)
    UHC not supported as a server encoding
    UTF8 all supported encodings
    WIN866 WIN866, ISO_8859_5, KOI8R, MULE_INTERNAL, UTF8, WIN1251
    WIN874 WIN874, UTF8
    WIN1250 WIN1250, LATIN2, MULE_INTERNAL, UTF8
    WIN1251 WIN1251, ISO_8859_5, KOI8R, MULE_INTERNAL, UTF8, WIN866
    WIN1252 WIN1252, UTF8
    WIN1253 WIN1253, UTF8
    WIN1254 WIN1254, UTF8
    WIN1255 WIN1255, UTF8
    WIN1256 WIN1256, UTF8
    WIN1257 WIN1257, UTF8
    WIN1258 WIN1258, UTF8

    要啟用自動字元集轉換,您必須告訴 PostgreSQL 您要在用戶端中使用的字元集(編碼)。有幾種方法可以實現此目的:

    • 在 psql 中使用 \encoding 指令。\encoding 允許您即時更改用戶端編碼。例如,要將編碼更改為 SJIS,請鍵入:

      1. \encoding SJIS
    • 使用 SET client_encoding TO。可以使用以下 SQL 指令設定用戶端編碼:

      1. SET CLIENT_ENCODING TO 'value';

      您還可以使用標準 SQL 語法 SET NAMES 來達到此目的:

      要查詢目前用戶端編碼:

      1. SHOW client_encoding;

      要回傳預設編碼:

    • 使用組態變數 client_encoding。如果設定了 變數,則在建立與伺服器的連線時會自動選擇該用戶端編碼。(這可以隨後使用上面提到的任何其他方法覆蓋。)

    如果無法轉換特定字元 - 假設您為伺服器選擇了 EUC_JP 而為用戶端選擇了 LATIN1,並且回傳了一些在 LATIN1 中沒有表示的日文字元 - 回報錯誤。

    如果用戶端字元集定義為 SQL_ASCII,則無論伺服器的字元集如何,都將停用編碼轉換。就像伺服器一樣,除非使用全 ASCII 資料,否則使用 SQL_ASCII 是不明智的。

    • CJKV 訊息處理:中文,日文,韓文和越南文運算
      • 包含 EUC_JP,EUC_CN,EUC_KR,EUC_TW 的詳細說明。
    • http://www.unicode.org/
      • Unicode Consortium 的網站。
    • RFC 3629
      • UTF-8 (8-bit UCS/Unicode Transformation Format) 定義在這裡