轉自:http://blog.chinaunix.net/uid-354915-id-3502551.htmlhtml
1、PostgreSQL的區域
區域屬性有如下幾個:
LC_COLLATE:字符串排序順序
LC_CTYPE:字符分類(什麼是字母?它是這個字母的等效大寫?)
LC_MESSAGES:信息的語言
LC_MONETARY:貨幣金額的格式
LC_NUMERIC:數字的格式
LC_TIME:日期和時間的格式
PostgreSQL 使用服務器操做系統提供的標準 ISO C 和 POSIX 區域機制。
區域支持是在使用 initdb 建立一個數據庫集羣的時候自動初始化的。
若是你的OS已經設置爲你的數據庫集羣想要的區域,那麼你就什麼也不用幹了。
若是你想要你的系統表現得像沒有區域支持同樣,那麼使用特殊的區域 C 或 POSIX
一些區域性質的值一旦運行了 initdb 以後,你就不再能更改它們了。LC_COLLATE 和 LC_CTYPE 就是這樣的。它們影響索引的排序順序,所以它們必需保持固定,其它區域性質能夠在服務器啓動的時候根據須要經過配置postgresql.conf變量來改變,若是你在 postgresql.conf 裏面刪除了這些缺省值,那麼服務器將會繼承來自運行環境的設置。
咱們談到從執行環境繼承區域的時候,好比字符集,按照下面的順序評估這些環境變量,直到找到一個已設置的:LC_ALL, LC_COLLATE, LANG 。若是這些環境變量一個都沒有設置,那麼區域缺省爲 C 。一些信息區域化庫也使用環境變量 LANGUAGE。
請檢查覈實 PostgreSQL 確實使用了你認爲它該用的區域設置。LC_COLLATE 和 LC_CTYPE 的設置都是在 initdb 時決定的,若是不重複 initdb 是不可能改變的。其它的區域設置包括 LC_MESSAGES 和 LC_MONETARY 都是由服務器的啓動環境決定的,可是能夠在運行時修改。你能夠用 SHOW 命令檢查數據庫正在使用的區域設置。前端
2、PostgreSQL的字符集
缺省的字符集是在使用 initdb 初始化數據庫集羣的時候選擇的。在你建立數據庫的時候是能夠覆蓋這個缺省的。所以,你能夠爲多個數據庫設置不一樣的字符集。
雖然你能夠給一個數據庫聲明你須要的任何編碼,但選擇一個與你選擇的區域不一致的編碼仍是不妥的作法。LC_COLLATE 和 LC_CTYPE 設置暗示一個特定的編碼,與區域相關的操做(好比排序)在不兼容的編碼裏頗有可能產生錯誤的解析。
一個安全使用多種編碼的方法是在 initdb 的時候把區域設置爲 C 或 POSIX ,這樣就關閉了任何實際的區域敏感性。
PostgreSQL 支持在服務器和前端之間的自動編碼轉換。
假如沒法進行特定的字符轉換,好比,你選的服務器編碼是 EUC_JP 而客戶端是 LATIN1 ,那麼有些日文字符不能轉換成 LATIN1 。這時將報告錯誤。sql
3、擴展:
一、常見編碼及轉換
UTF8 = UNICODE8;
UNICODE16是咱們常常說的UNICODE;
GBK即漢字內碼擴展規範,GBK是ANSI的一種,用0x80~0xFF 範圍的2個字節來表示1個字符,根據微軟資料,GBK是對GB2312-80的擴展,也就是CP936字碼表;
windows英文版默認的應該是windows1252;
windows中文版用的是GB2312/GBK(用dos命令chcp查看,936爲簡體中文);
liunx不少默認編碼都是utf-8,可是你能夠經過命令設置成GB2312;
網頁編碼,一般是跟編輯網頁的編輯器有關,好比說你的編輯器設置爲GB2312字符集,那麼你的網頁的編碼就是GB2312的。若是你用英文的操做系統打開就會是亂碼。不過如今的瀏覽器都支持字符集識別,它會幫你把GB2312編碼的網頁自動轉換爲unicode的網頁,從而解決亂碼的問題。
若是你的文件編碼是GBK,而你的系統環境是windows1252英文環境,那麼這時候你打開文件就會是亂碼的;
解決方案有兩種:
(1)改變系統的語言爲中文就能夠解決亂碼的問題;
(2)將GBK編碼的文件轉換爲unicode編碼,unicode編碼是萬國碼,通常的操做系統都支持,不存在打開後亂碼的問題。
每種編碼都有本身的二進制編碼集,平時常常遇到的問題是:
(1)對字符進行了錯誤的編碼解析,致使出現亂碼;
(2)字符在兩個字符集中都存在,致使這部分字符變成「?」。
二、數據庫編程的編碼問題
數據庫編程設計的編碼問題包括三個方面:
數據庫服務器編碼;
數據庫客戶端編碼;
本地環境編碼。
(1)數據庫服務器字符編碼:
數據庫服務器支持某種編碼,是指數據庫服務器可以從客戶端接收、存儲以及向客戶端提供該種編碼的字符,並能將該種編碼的字符轉換到其它編碼。
查看PostgreSQL數據庫服務器端編碼:
postgres=# show server_encoding;
server_encoding
-----------------
UTF8
postgres=# \l
名稱 | 擁有者 | 字元編碼 | Collate | Ctype | TestDb1 | TestRole1 | UTF8 | Chinese (Simplified)_People's Republic of China.936 | Chinese (Simplified)_People's Republic of China.936 |
TestDb2 | postgres | UTF8 | Chinese (Simplified)_People's Republic of China.936 | Chinese (Simplified)_People's Republic of China.936 |
postgres | postgres | UTF8 | Chinese (Simplified)_People's Republic of China.936 | Chinese (Simplified)_People's Republic of China.936 |
template0 | postgres | UTF8 | Chinese (Simplified)_People's Republic of China.936 | Chinese (Simplified)_People's Republic of China.936 |
(2)數據庫客戶端字符編碼:
客戶端工具支持某種編碼,必須可以顯示從數據庫讀取的該種編碼的字符,也能經過本工具將該種編碼的字符提交到給服務器端。
查看PostgreSQL客戶端工具psql編碼:
postgres=# show client_encoding;
GBK
postgres=# \encoding
GBK
指定Postgresql會話的客戶端編碼:
postgres=# set client_encoding to 'utf8';
SET
postgres=# show client_encoding;
client_encoding
-----------------
UTF8
(3)本地環境編碼:
若是使用dos的命令行界面,本地環境就是指dos命令行環境的編碼,可使用dos命令chcp查看dos環境編碼:
D:\Program Files\PowerCmd>chcp
活動代碼頁: 936
----936爲簡體中文,GBK;
若是在使用某種編輯器,則本地環境編碼取該編輯器的編碼設置。數據庫
4、實例
雖然PG支持客戶端和服務器端的編碼自動轉換,可是還須要聽從一個原則:本地環境的編碼和客戶端編碼需一致。
一、PostgreSQL的數據庫postgres,服務器端字符編碼爲utf8,客戶端工具psql字符編碼爲GBK,本地環境dos命令編輯器編碼爲GBK,此時:
postgres=# show server_encoding;
server_encoding
-----------------
UTF8
(1 行記錄)
postgres=# show client_encoding;
client_encoding
-----------------
GBK
(1 行記錄)
postgres=# \! chcp
活動代碼頁: 936
postgres=# select * from "TestTb1";
Column1
-----------
測試
11
因爲本地環境和客戶端編碼都是GBK,一致,沒有問題;
insert時,客戶端接收本地環境輸入的GBK字符(二者都爲GBK),客戶端傳到服務器端時自動轉換爲UTF-8編碼存儲,沒有問題;
select時,服務器端傳到客戶端,UTF-8編碼自動轉換爲GBK編碼,在本地環境顯示時,本地環境就是GBK編碼,顯示沒有問題。編程
二、PostgreSQL的數據庫postgres,服務器端字符編碼爲utf8,客戶端工具psql字符編碼爲utf8,本地環境dos命令編輯器編碼爲GBK,此時:
postgres=# set client_encoding to 'utf8';
SET
postgres=# insert into test values('測試1');
閿欒?: 鏃犳晥鐨?"UTF8" 緙栫爜瀛楄妭欏哄簭: 0xb2
postgres=# select * from test;
column1
--------------------
嫺嬭瘯
(1 行記錄)
因爲客戶端和服務器的編碼一致,故不進行轉碼,
insert時,本地輸入的GBK編碼到客戶端不自動轉換,客戶端把接收的字符做爲utf編碼傳給服務器端不轉換,GBK的編碼做爲UTF-8存儲,故有問題。
報錯的信息爲:ERROR: invalid byte sequence for encoding "UTF8": 0xb2;
select時,服務端的utf編碼傳給客戶端不轉換,客戶端把utf編碼傳給本地環境不自動轉換,utf8編碼用gbk編碼顯示,故有問題。windows
三、本地環境就是指此時使用的環境,起初我使用powercmd代替windows的cmd命令行工具,實現上面第1個實例是老是失敗(亂碼)。
緣由就是,此時本地環境編碼是指powercmd的編碼,而不是執行chcp命令獲得的編碼。
而powercmd使用的編碼到底是什麼,我也沒有找到。瀏覽器