PG 字符集設定(轉帖)

babyyellow發表於2011-12-20
中文環境下PostgreSQL的使用

galy ()




雖然官方文件有提到編碼的問題,但是對於中文講的比較簡單,給中文的PostgreSQL使用者帶來很多困擾,本文簡單簡述一下中文環境下PostgreSQL如何正確設定編碼。

一、伺服器端的編碼設定

PostgreSQL在伺服器端只支援兩種簡體中文編碼: EUC_CN和UTF-8,而由於windows不支援EUC所以,在windows環境底下只能選UTF-8。

1. 安裝時的編碼設定

1.1 Linux下的中文編碼設定

設定為EUC_CN
[localhost ~]$ initdb -E EUC_CN -D data7 --locale=zh_CN

設定為UTF-8
[galy@localhost ~]$ initdb -E UTF-8 -D data7 --locale=zh_CN.UTF-8

1.2 Windows下的中文編碼設定

設定為UTF-8
initdb.exe -E UTF8  -D c:\data3  --locale=chinese

2. 常見的問題:

2.1 不支援的伺服器編碼

如果環境的預設編碼是PostgreSQL不支援的話,初始化的時候會報錯,如下面環境的中文編碼為GBK,而PG不支援GBK,所以報錯。
[localhost ~]$ export LANG=zh_CN.gbk
[localhost ~]$ initdb -D testencoding

The database cluster will be initialized with locale zh_CN.gbk.
initdb: locale zh_CN.gbk requires unsupported encoding GBK
Encoding GBK is not allowed as a server-side encoding.
Rerun initdb with a different locale selection.

2.2 locale和編碼有衝突

如果指定的locale和編碼格式有衝突,同樣也會報錯。解決的方便是,指定編碼相容的locale.

[localhost ~]$ locale
LANG=zh_CN.gbk
LC_CTYPE="zh_CN.gbk"

預設的locale是中文gbk, 而下面的編碼確實EUC_CN,因而系統報錯,解決的方法是,指定--locale=zh_CN

[localhost ~]$ initdb -E EUC_CN -D data6
The files belonging to this database system will be owned by user "galy".
This user must also own the server process.

The database cluster will be initialized with locale zh_CN.gbk.
initdb: encoding mismatch
The encoding you selected (EUC_CN) and the encoding that the
selected locale uses (GBK) do not match.  This would lead to
misbehavior. in various character string processing functions.
Rerun initdb and either do not specify an encoding explicitly,
or choose a matching combination.

initdb: 警告: 編碼不匹配
您選擇的編碼 (EUC_CN) 和所選擇的語言環境使用的編碼 (GBK) 不匹配的.
這樣將導致處理不同字串的函式時產生錯誤.
要修復此問題, 重新執行 initdb 並且不要明確指定編碼, 或者先選擇一個匹配
組合型別.

二、客戶端的編碼

雖然PG支援客戶端和伺服器端的編碼自動轉換,但是還需要遵從一個原則:本地環境的編碼和客戶端編碼需一致。否則將會出現亂碼或者是其他問題。

本地環境的編碼為GBK
C:\Program Files\PostgreSQL\9.1\bin>chcp
活動內碼表: 936

資料庫的編碼為UTF8
=#\t
Name              | lenovo
Owner             | lenovo
Encoding          | UTF8
Collate           | Chinese (Simplified)_People's Republic of China.936
Ctype             | Chinese (Simplified)_People's Republic of China.936
Access privileges |

客戶端編碼為GBK
lenovo=# \encoding
GBK

現在本地環境和客戶端編碼都是GBK,所以沒有問題
客戶端輸入的GBK字元,會自動轉化為UTF-8
lenovo=# insert into test values('測試');
INSERT 0 1

伺服器端的UTF-8編碼,傳到客戶端時候,也會自動轉換編碼為GBK:
lenovo=# select * from test;
name
------
測試
(1 row)

如果客戶端設定為UTF-8的話,和本地環境的GBK不一致則會出現問題
lenovo=# \encoding UTF-8

由於客戶端編碼和伺服器端一致,為UTF-8,所以不轉換傳到客戶端,而作業系統把它當作GBK顯示,所以顯示亂碼:
lenovo=# select * from test;
name
------
嫻嬭瘯
(1 row)

而插入的字元則直接以GBK編碼的形式傳到伺服器端,伺服器端認識不了,所以報錯。
lenovo=# insert into test values('測試');
ERROR:  invalid byte sequence for encoding "UTF8": 0xb2
ERROR:  invalid byte sequence for encoding "UTF8": 0xb2

輸入和顯示都有問題,這是因為如果客戶端和伺服器的編碼都一致的話,則不進行轉碼,而輸入是按照本地環境的GBK進行編碼,GBK的編碼進入UTF-8的庫當然會有問題。

三、顯示資訊的中文話

PostgreSQL支援多語言顯示提示資訊,如果希望伺服器端及客戶端的提示資訊為中文,還需要進行一些額外的設定。

首先, 編譯的時候需要加上自然語言支援模組

./configure --enable-nls

其次,在引數配置檔案postgresql.conf設定資訊為中文

lc_messages = 'zh_CN'                     # locale for system error message

這樣在伺服器端和客戶端的提示資訊都顯示為中文

[localhost ~]$
日誌:  已啟動autovacuum
日誌:  資料庫系統準備接受連線

# dsd;
錯誤:  語法錯誤 在 "dsd" 或附近的 第 1 個字元處
語句:  dsd;
錯誤:  語法錯誤 在 "dsd" 或附近的

來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/133735/viewspace-713623/,如需轉載,請註明出處,否則將追究法律責任。

相關文章