PostgreSQL 區(qū)域支持

2021-08-31 15:48 更新
23.1.1. 概述
23.1.2. 行為
23.1.3. 問題

區(qū)域支持指的是應(yīng)用遵守文化偏好的問題,包括字母表、排序、數(shù)字格式等。PostgreSQL使用服務(wù)器操作系統(tǒng)提供的標(biāo)準(zhǔn) ISO C 和POSIX的區(qū)域機制。更多的信息請參考你的系統(tǒng)的文檔。

23.1.1. 概述

區(qū)域支持是在使用initdb創(chuàng)建一個數(shù)據(jù)庫集簇時自動被初始化的。默認情況下,initdb將會按照它的執(zhí)行環(huán)境的區(qū)域設(shè)置初始化數(shù)據(jù)庫集簇; 因此如果你的系統(tǒng)已經(jīng)設(shè)置為你的數(shù)據(jù)庫集簇想要使用的區(qū)域, 那么你就沒有什么可干的。如果你想使用其它的區(qū)域(或者你還不知道你的系統(tǒng)設(shè)置的區(qū)域是什么),那么你可以用--locale選項準(zhǔn)確地告訴 initdb你要用哪一個區(qū)域。 比如:

initdb --locale=sv_SE

這個Unix系統(tǒng)上的例子把區(qū)域設(shè)置為瑞典(SE)瑞典語(sv)。 其他的可能性包括 en_US(美國英語)和fr_CA(加拿大法語)。如果有多于一種字符集可以用于區(qū)域,那么聲明可以采用如下的形式:language_territory.codeset。例如 fr_BE.UTF-8表示在比利時(BE)講的法語(fr),使用一個UTF-8字符集編碼。

在你的系統(tǒng)上有哪些區(qū)域可用取決于操作系統(tǒng)提供商提供了什么以及安裝了什么。在大部分Unix系統(tǒng)上,命令locale -a將會提供一個所有可用區(qū)域的列表。Windows使用一些更繁瑣的區(qū)域名,例如German_Germany或者Swedish_Sweden.1252,但是其原則是相同的。

有時候,把幾種區(qū)域規(guī)則混合起來也很有用,比如,使用英語排序規(guī)則而用西班牙語消息。 為了支持這些,我們有一套區(qū)域子類用于控制本地化規(guī)則的某些方面:

LC_COLLATE 字符串排序順序
LC_CTYPE 字符分類(什么是一個字符?它的大寫形式是否等效?)
LC_MESSAGES 消息使用的語言Language of messages
LC_MONETARY 貨幣數(shù)量使用的格式
LC_NUMERIC 數(shù)字的格式
LC_TIME 日期和時間的格式

這些類名轉(zhuǎn)換成initdb的選項名來覆蓋某個特定分類的區(qū)域選擇。比如,要把區(qū)域設(shè)置為加拿大法語,但使用 U.S. 規(guī)則格式化貨幣,可以使用initdb --locale=fr_CA --lc-monetary=en_US。

如果你想讓系統(tǒng)表現(xiàn)得象沒有區(qū)域支持,那么使用特殊的區(qū)域名C或者等效的POSIX。

一些區(qū)域分類的值必需在數(shù)據(jù)庫被創(chuàng)建時的就被固定。你可以為不同的數(shù)據(jù)庫使用不同的設(shè)置,但是一旦一個數(shù)據(jù)庫被創(chuàng)建,你就不能在數(shù)據(jù)庫上修改這些區(qū)域分類的值。LC_COLLATELC_CTYPE就是這樣的分類。它們影響索引的排序順序,因此它們必需保持固定, 否則在文本列上的索引將會崩潰(但是你可以使用排序規(guī)則放松這種限制,討論見第 23.2 節(jié))。這些分類的默認值在initdb運行時被確定,并且這些值在新數(shù)據(jù)庫被創(chuàng)建時使用,除非在CREATE DATABASE命令中特別指定。

其它區(qū)域分類可以在任何時候被更改,更改的方式是設(shè)置與區(qū)域分類同名的服務(wù)器配置參數(shù)(詳見第 19.11.2 節(jié))。被initdb選中的值實際上只是被寫入到配置文件postgresql.conf中作為服務(wù)器啟動時的默認值。如果你將這些賦值從 postgresql.conf中除去,那么服務(wù)器將會從其執(zhí)行環(huán)境中繼承該設(shè)置。

請注意服務(wù)器的區(qū)域行為是由它看到的環(huán)境變量決定的,而不是由任何客戶端的環(huán)境變量影響的。 因此,我們要在啟動服務(wù)器之前認真地設(shè)置好這些變量。這樣帶來的一種后果是如果客戶端和服務(wù)器設(shè)置成不同的區(qū)域, 那么消息可能以不同的語言呈現(xiàn),實際情況取決于它們的起源地。

注意

在我們談到從執(zhí)行環(huán)境繼承區(qū)域的時候,我們的意思是在大多數(shù)操作系統(tǒng)上的下列動作: 對于一個給定的區(qū)域分類,比如排序規(guī)則,按照下面的順序評估這些環(huán)境變量, 直到找到一個被設(shè)置了的:LC_ALL、 LC_COLLATE(或者對應(yīng)于相應(yīng)分類的變量)、LANG。如果這些環(huán)境變量一個都沒有被設(shè)置,那么將區(qū)域缺省設(shè)置為C。

一些消息本地化庫也查看環(huán)境變量LANGUAGE,它覆蓋所有其它用于設(shè)置消息語言的區(qū)域設(shè)置。如果有疑問, 請參考你的操作系統(tǒng)的文檔,特別是有關(guān)gettext的文檔。

要允許消息被翻譯成用戶喜歡的語言,編譯時必需打開NLSconfigure --enable-nls)。所有其他區(qū)域支持都會被自動編譯。

23.1.2. 行為

區(qū)域設(shè)置特別影響下面的 SQL 特性:

  • 在文本數(shù)據(jù)上使用ORDER BY或標(biāo)準(zhǔn)比較操作符的查詢中的排序順序

  • 函數(shù)upper、lowerinitcap

  • 模式匹配操作符(LIKE、SIMILAR TO和POSIX風(fēng)格的正則表達式);區(qū)域影響大小寫不敏感匹配和通過字符類正則表達式的字符分類

  • to_char函數(shù)家族

  • LIKE子句使用索引的能力

PostgreSQL中使用非C或非POSIX區(qū)域的缺點是性能影響。它降低了字符處理的速度并且阻止了在LIKE中對普通索引的使用。因此,只能在真正需要的時候才使用它。

作為允許PostgreSQL在非 C 區(qū)域下為LIKE子句使用索引, 有好幾種自定義操作符類可用。這些操作符類允許創(chuàng)建一個執(zhí)行嚴格按字符比較的索引。詳見第 11.10 節(jié)。另一種方法是創(chuàng)建使用 C排序規(guī)則的索引,如第 23.2 節(jié)所討論的。

23.1.3. 問題

如果根據(jù)上面解釋區(qū)域支持仍然不能運轉(zhuǎn),檢查一下操作系統(tǒng)的區(qū)域支持是否被正確配置。 要檢查系統(tǒng)中安裝了哪些區(qū)域,你可以使用命令locale -a(如果你的操作系統(tǒng)提供了該命令)。

請檢查PostgreSQL確實正在使用你認為它該用的區(qū)域設(shè)置。LC_COLLATELC_CTYPE設(shè)置都是在數(shù)據(jù)庫創(chuàng)建時決定的,并且在除了創(chuàng)建數(shù)據(jù)庫之外的操作中都不能被更改。其它的區(qū)域設(shè)置包括LC_MESSAGESLC_MONETARY都是由服務(wù)器啟動的環(huán)境決定的, 但是可以在運行時修改。你可以用SHOW命令檢查活躍的區(qū)域設(shè)置。

源代碼目錄的src/test/locale中包含PostgreSQL的區(qū)域支持的測試套件。

那些通過分析錯誤消息來處理服務(wù)器端錯誤的客戶端應(yīng)用很明顯會有問題,因為服務(wù)器來的消息可能會是以不同語言表示的。 我們建議這類應(yīng)用的開發(fā)人員改用錯誤代碼機制。

維護消息翻譯目錄需要許多志愿者的堅持不懈的努力, 他們希望PostgreSQL以他們的語言說話。 如果以你的語言表示的消息目前還不可用或者沒有完全翻譯完成,那么我們很感謝你的協(xié)助。如果你想幫忙,那么請參考第 54 章或者向開發(fā)者郵遞列表發(fā)郵件。


以上內(nèi)容是否對您有幫助:
在線筆記
App下載
App下載

掃描二維碼

下載編程獅App

公眾號
微信公眾號

編程獅公眾號