2025年9月25日: PostgreSQL 18 釋出!
支援的版本: 當前 (18) / 17 / 16 / 15 / 14 / 13
開發版本: 開發版
不支援的版本: 12 / 11 / 10 / 9.6 / 9.5 / 9.4 / 9.3 / 9.2 / 9.1 / 9.0 / 8.4 / 8.3 / 8.2

23.1. 區域設定支援 #

區域設定支援是指應用程式遵循關於字母表、排序、數字格式等方面的文化偏好。PostgreSQL 使用標準的 ISO C 和POSIX伺服器作業系統提供的區域設定功能。有關更多資訊,請參閱您系統的文件。

23.1.1. 概述 #

區域設定支援在建立資料庫叢集時使用 initdb 自動初始化。預設情況下,initdb 將使用其執行環境的區域設定來初始化資料庫叢集,因此,如果您的系統已設定為使用您想要的資料庫叢集區域設定,則無需執行其他操作。如果您想使用不同的區域設定(或不確定您的系統設定了哪個區域設定),則可以透過指定 --locale 選項來明確指示 initdb 使用哪個區域設定。例如:

initdb --locale=sv_SE

此 Unix 系統示例將區域設定設定為瑞典語(sv),在瑞典(SE)使用。其他可能的設定包括 en_US(美式英語)和 fr_CA(加拿大法語)。如果一個區域設定可以使用多種字元集,則規範可以採用 語言_地區.字元集 的形式。例如,fr_BE.UTF-8 代表在比利時(BE)使用的法語(fr),使用UTF-8字元集編碼。

您的系統上可用的區域設定及其名稱取決於作業系統供應商提供的以及安裝的內容。在大多數 Unix 系統上,locale -a 命令將提供可用區域設定的列表。Windows 使用更冗長的區域設定名稱,例如 German_GermanySwedish_Sweden.1252,但原理是相同的。

有時將來自多個區域設定的規則混合使用很有用,例如,使用英語的排序規則但訊息使用西班牙語。為了支援這一點,存在一組區域設定子類別,它們僅控制本地化規則的某些方面:

LC_COLLATE 字串排序順序
LC_CTYPE 字元分類(什麼是字母?其大寫等價物是什麼?)
LC_MESSAGES 訊息語言
LC_MONETARY 貨幣金額的格式化
LC_NUMERIC 數字的格式化
LC_TIME 日期和時間的格式化

這些類別名稱對應於 initdb 的選項名稱,用於覆蓋特定類別的區域設定選擇。例如,要將區域設定設定為加拿大法語,但使用美國規則格式化貨幣,請使用 initdb --locale=fr_CA --lc-monetary=en_US

如果您希望系統表現得好像沒有區域設定支援一樣,請使用特殊區域設定名稱 C,或等同的 POSIX

某些區域設定類別在建立資料庫時必須固定其值。您可以為不同的資料庫使用不同的設定,但一旦資料庫建立完成,就無法再更改該資料庫的設定。LC_COLLATELC_CTYPE 是這些類別。它們影響索引的排序順序,因此必須保持固定,否則文字列上的索引會損壞。(但您可以使用排序規則來減輕此限制,如 第 23.2 節中所述。)這些類別的預設值在執行 initdb 時確定,並且新資料庫建立時將使用這些值,除非在 CREATE DATABASE 命令中另有指定。

其他區域設定類別可以隨時更改,方法是設定與區域設定類別同名的伺服器配置引數(有關詳細資訊,請參閱 第 19.11.2 節)。initdb 選擇的值實際上只寫入 postgresql.conf 配置檔案中,作為伺服器啟動時的預設值。如果從 postgresql.conf 中刪除這些賦值,伺服器將繼承其執行環境的設定。

請注意,伺服器的區域設定行為由伺服器看到的 arement 變數決定,而不是由任何客戶端的 arement 決定。因此,請務必在啟動伺服器之前配置正確的區域設定。其後果是,如果客戶端和伺服器在不同的區域設定中設定,訊息可能會顯示為不同的語言,具體取決於其來源。

注意

當我們談論從執行環境繼承區域設定時,在大多數作業系統上意味著:對於給定的區域設定類別,例如排序,將按照以下順序檢查 arement 變數,直到找到一個已設定的變數為止:LC_ALLLC_COLLATE(或對應於相應類別的變數)、LANG。如果這些 arement 變數均未設定,則區域設定預設為 C

某些訊息本地化庫還檢查 LANGUAGE arement 變數,該變數會覆蓋所有其他區域設定,用於設定訊息的語言。如有疑問,請參考您的作業系統文件,特別是關於 gettext 的文件。

要使訊息能夠翻譯成使用者偏好的語言,NLS必須在構建時選擇(configure --enable-nls)。所有其他區域設定支援都是自動內建的。

23.1.2. 行為 #

區域設定會影響以下 SQL 功能:

  • 使用 ORDER BY 或文字資料的標準比較運算子的查詢中的排序順序

  • upperlowerinitcap 函式

  • 模式匹配運算子(LIKESIMILAR TO 和 POSIX 風格的正則表示式);區域設定會影響不區分大小寫的匹配以及字元類正則表示式的字元分類

  • to_char 系列函式

  • 使用 LIKE 子句的索引的能力

PostgreSQL 中使用非 CPOSIX 區域設定的缺點是其效能影響。它會減慢字元處理速度,並阻止普通索引被 LIKE 使用。因此,僅在您確實需要時才使用區域設定。

作為一種變通方法,允許 PostgreSQL 在非 C 區域設定下使用帶 LIKE 子句的索引,存在幾種自定義運算子類。這些允許建立執行嚴格逐字元比較的索引,忽略區域設定比較規則。有關更多資訊,請參閱 第 11.10 節。另一種方法是建立使用 C 排序規則的索引,如 第 23.2 節中所述。

23.1.3. 選擇區域設定 #

根據需求,可以在不同的作用域中選擇區域設定。以上概述展示瞭如何使用 initdb 指定區域設定來設定整個叢集的預設值。以下列表顯示了可以在何處選擇區域設定。每個專案為後續專案提供預設值,每個較低的專案允許在更精細的粒度上覆蓋預設值。

  1. 如上所述,作業系統環境為新初始化資料庫叢集的區域設定提供了預設值。在許多情況下,這就足夠了:如果作業系統已配置為所需的語言/地區,則預設情況下 PostgreSQL 也會根據該區域設定執行。

  2. 如上所示,initdb 的命令列選項為新初始化的資料庫叢集指定區域設定。如果作業系統沒有您想要的資料庫系統的區域設定配置,則使用此選項。

  3. 可以為每個資料庫單獨選擇區域設定。SQL 命令 CREATE DATABASE 及其命令列等效命令 createdb 具有相應的選項。例如,如果一個數據庫叢集包含多個具有不同需求的租戶的資料庫,則可以使用此選項。

  4. 可以為單個表列設定區域設定。這使用一個稱為排序規則的 SQL 物件,並在 第 23.2 節中進行了說明。例如,使用此選項可以以不同語言對資料進行排序,或自定義特定表的排序順序。

  5. 最後,可以為單個查詢選擇區域設定。同樣,這使用 SQL 排序規則物件。這可以用於根據執行時選擇更改排序順序,或用於臨時實驗。

23.1.4. 區域設定提供程式 #

區域設定提供程式指定哪個庫定義了排序規則和字元分類的區域設定行為。

用於選擇區域設定的命令和工具(如上所述)都具有選擇區域設定提供程式的選項。以下是一個使用 ICU 提供程式初始化資料庫叢集的示例:

initdb --locale-provider=icu --icu-locale=en

有關詳細資訊,請參閱相應命令和程式的說明。請注意,您可以在不同粒度上混合使用區域設定提供程式,例如,為叢集預設使用 libc,但有一個數據庫使用 icu 提供程式,然後在這些資料庫中使用任一提供程式的排序規則物件。

無論使用哪種區域設定提供程式,作業系統仍用於提供某些區域設定感知行為,例如訊息(請參閱 lc_messages)。

下面列出了可用的區域設定提供程式:

builtin

內建提供程式使用內建操作。此提供程式僅支援 CC.UTF-8PG_UNICODE_FAST 區域設定。

C 區域設定的行為與 libc 提供程式中的 C 區域設定相同。使用此區域設定時,行為可能取決於資料庫編碼。

C.UTF-8 區域設定僅在資料庫編碼為 UTF-8 時可用,並且行為基於 Unicode。排序規則僅使用程式碼點值。正則表示式字元類基於“POSIX 相容”語義,大小寫對映是“簡單”變體。

PG_UNICODE_FAST 區域設定僅在資料庫編碼為 UTF-8 時可用,並且行為基於 Unicode。排序規則僅使用程式碼點值。正則表示式字元類基於“標準”語義,大小寫對映是“完整”變體。

icu

ICU 提供程式使用外部 ICU 庫。PostgreSQL 必須已配置為支援 ICU。

ICU 提供與作業系統和資料庫編碼無關的排序和字元分類行為,如果您希望在不改變結果的情況下遷移到其他平臺,這可能是首選。LC_COLLATELC_CTYPE 可以獨立於 ICU 區域設定進行設定。

注意

對於 ICU 提供程式,結果可能取決於所使用的 ICU 庫版本,因為該庫會隨著時間的推移而更新以反映自然語言的變化。

libc

libc 提供程式使用作業系統的 C 庫。排序和字元分類行為由 LC_COLLATELC_CTYPE 設定控制,因此它們不能獨立設定。

注意

在使用 libc 提供程式時,相同的區域設定名稱在不同平臺上可能有不同的行為。

23.1.5. ICU 區域設定 #

23.1.5.1. ICU 區域設定名稱 #

ICU 區域設定名稱的格式是語言標籤

CREATE COLLATION mycollation1 (provider = icu, locale = 'ja-JP');
CREATE COLLATION mycollation2 (provider = icu, locale = 'fr');

23.1.5.2. 區域設定規範化和驗證 #

在定義新的 ICU 排序物件或以 ICU 為提供程式的資料庫時,給定的區域設定名稱將被轉換(“規範化”)為語言標籤,如果它還沒有采用該形式。例如:

CREATE COLLATION mycollation3 (provider = icu, locale = 'en-US-u-kn-true');
NOTICE:  using standard form "en-US-u-kn" for locale "en-US-u-kn-true"
CREATE COLLATION mycollation4 (provider = icu, locale = 'de_DE.utf8');
NOTICE:  using standard form "de-DE" for locale "de_DE.utf8"

如果您看到此通知,請確保 providerlocale 是預期的結果。為了在使用 ICU 提供程式時獲得一致的結果,請指定規範化的語言標籤,而不是依賴轉換。

沒有語言名稱的區域設定,或特殊語言名稱 root,將被轉換為語言 und(“未定義”)。

ICU 可以將大多數 libc 區域設定名稱以及一些其他格式轉換為語言標籤,以便更容易地遷移到 ICU。如果 ICU 中使用了 libc 區域設定名稱,其行為可能與 libc 中不完全相同。

如果解釋區域設定名稱時出現問題,或者區域設定名稱代表 ICU 無法識別的語言或地區,您將看到以下警告:

CREATE COLLATION nonsense (provider = icu, locale = 'nonsense');
WARNING:  ICU locale "nonsense" has unknown language "nonsense"
HINT:  To disable ICU locale validation, set parameter icu_validation_level to DISABLED.
CREATE COLLATION

icu_validation_level 控制如何報告訊息。除非設定為 ERROR,否則排序規則仍會建立,但行為可能不是使用者期望的。

23.1.5.3. 語言標籤 #

語言標籤(在 BCP 47 中定義)是用於標識語言、地區和其他關於區域設定資訊的標準化識別符號。

基本語言標籤只是 語言-地區;甚至可以只包含 語言語言 是語言程式碼(例如,法語是 fr),地區 是地區程式碼(例如,加拿大是 CA)。示例:ja-JPdefr-CA

排序設定可以包含在語言標籤中以自定義排序行為。ICU 允許廣泛的自定義,例如對重音符號、大小寫和標點符號的敏感性(或不敏感性);數字在文字中的處理方式;以及許多其他選項,以滿足各種用途。

要在語言標籤中包含此附加的排序資訊,請附加 -u,它表示存在附加的排序設定,後跟一個或多個 -- 對。排序設定的鍵, 是該設定的有效值。對於布林設定,可以省略 -,只指定 -,表示值為 true

例如,語言標籤 en-US-u-kn-ks-level2 表示美國地區的英語語言區域設定,排序設定 kntruekslevel2。這些設定意味著排序將不區分大小寫,並將數字序列視為一個整體數字。

CREATE COLLATION mycollation5 (provider = icu, deterministic = false, locale = 'en-US-u-kn-ks-level2');
SELECT 'aB' = 'Ab' COLLATE mycollation5 as result;
 result
--------
 t
(1 row)

SELECT 'N-45' < 'N-123' COLLATE mycollation5 as result;
 result
--------
 t
(1 row)

有關詳細資訊和使用具有自定義排序資訊的語言標籤的附加示例,請參閱 第 23.2.3 節

23.1.6. 問題 #

如果區域設定支援不起作用,請檢查作業系統中的區域設定支援是否已正確配置。要檢查您的系統上安裝了哪些區域設定,您可以使用 locale -a 命令,如果您的作業系統提供了該命令。

檢查 PostgreSQL 是否實際使用了您認為它應該使用的區域設定。LC_COLLATELC_CTYPE 設定在建立資料庫時確定,除非建立新資料庫,否則無法更改。其他區域設定包括 LC_MESSAGESLC_MONETARY,它們最初由伺服器啟動時的環境決定,但可以動態更改。您可以使用 SHOW 命令檢查活動的區域設定。

原始碼發行版中的 src/test/locale 目錄包含一個用於 PostgreSQL 區域設定支援的測試套件。

透過解析錯誤訊息文字來處理伺服器端錯誤的客戶端應用程式,在伺服器訊息語言不同時顯然會遇到問題。此類應用程式的作者應改用錯誤程式碼方案。

維護訊息翻譯目錄需要大量志願者持續的努力,他們希望看到 PostgreSQL 能夠很好地支援他們喜歡的語言。如果您的語言的訊息當前不可用或未完全翻譯,我們將非常感謝您的協助。如果您想幫忙,請參閱 第 56 章或寫信給開發人員郵件列表。

提交更正

如果您在文件中看到任何不正確、與您對特定功能的體驗不符或需要進一步澄清的內容,請使用此表格報告文件問題。