作者: Tatsuo Ishii, 最後更新:2002-07-24. 參考 Tatsuo 的 網站 獲取更多資訊.
多字節支援 (MB)是為了讓 PostgreSQL 能夠處理多字節字元集,比如 EUC (擴展 Unix 編碼 Extended Unix Code),Unicode 和 Mule 國際編碼.把 MB 打開, 你就能在正則表達式(regexp) LIKE,和一些其它函數裡使用多字節字元集了. 預設的編碼系統是在你用 initdb 初始化 PostgreSQL 系統安裝的時候 確立的.請注意這個預設是可以在使用 createdb 或者 SQL 命令CREATE DATABASE 建立資料庫的時候覆蓋的.所以你可以擁有多個有著不同編碼系統的資料庫. 請注意 MB 可以處理類似 ISO-8859-1 這樣的單字節字元集。
自PostgreSQL版本 7.3 起,多字節支援就是預設的了。
下面的字元集可以用做資料庫編碼。
Table 5-1. 字元集編碼
| 編碼 | 描述 |
|---|---|
| SQL_ASCII | US ASCII |
| EUC_JP | 日文 EUC |
| EUC_CN | 中文 EUC |
| EUC_KR | 韓文 EUC |
| JOHAB | 韓文 EUC (Hangle base) |
| EUC_TW | 台灣 EUC |
| UNICODE | Unicode(UTF-8) |
| MULE_INTERNAL | Mule 內部編碼 |
| LATIN1 | ISO 8859-1 ECMA-94 Latin Alphabet No.1 |
| LATIN2 | ISO 8859-2 ECMA-94 Latin Alphabet No.2 |
| LATIN3 | ISO 8859-3 ECMA-94 Latin Alphabet No.3 |
| LATIN4 | ISO 8859-4 ECMA-94 Latin Alphabet No.4 |
| LATIN5 | ISO 8859-9 ECMA-128 Latin Alphabet No.5 |
| LATIN6 | ISO 8859-10 ECMA-144 Latin Alphabet No.6 |
| LATIN7 | ISO 8859-13 Latin Alphabet No.7 |
| LATIN8 | ISO 8859-14 Latin Alphabet No.8 |
| LATIN9 | ISO 8859-15 Latin Alphabet No.9 |
| LATIN10 | ISO 8859-16 ASRO SR 14111 Latin Alphabet No.10 |
| ISO-8859-5 | ECMA-113 Latin/Cyrillic |
| ISO-8859-6 | ECMA-114 Latin/Arabic |
| ISO-8859-7 | ECMA-118 Latin/Greek |
| ISO-8859-8 | ECMA-121 Latin/Hebrew |
| KOI8 | KOI8-R(U) |
| WIN | Windows CP1251 |
| ALT | Windows CP866 |
| WIN1256 | 阿拉伯語 Windows CP1256 |
| TCVN | 越南語 TCVN-5712(Windows CP1258) |
| WIN874 | 泰語(Thai) Windows CP874 |
Important: 在 PostgreSQL7.2 之前, LATIN5錯誤地表示 ISO 8859-5 的意思. 從 7.2 開始 LATIN5表示 ISO8859-9. 如果你有一個在 7.1 或者之前建立的 使用了 LATIN5的資料庫, 而且你希望移植到 7.2(或者以後的版本), 那麼你必須非常仔細地 注意這個變化.
Important: 並非所有API支援上面列出的編碼.比如, PostgreSQL JDBC 驅動就不支援MULE_INTERNAL, LATIN6,LATIN8 和 LATIN10.
initdb 為一次 PostgreSQL 安裝定義預設的編碼系統,比如:
$ initdb -E EUC_JP
把預設編碼設定為 EUC_JP (用於日文的擴展的 Unix 編碼). 如果你喜歡用長選項宣告的話,你可以用 --encoding 代替 -E. 如果沒有給出-E或者--encoding選項, 則使用 SQL_ASCII。
你可以建立一個有著不同編碼的資料庫:
$ createdb -E EUC_KR korean
將建立一個帶有EUC_KR編碼的名字叫 korean 的資料庫. 另外一種實現方法是使用 SQL 命令:
CREATE DATABASE korean WITH ENCODING = 'EUC_KR';
資料庫的編碼是用系統表 pg_database 裡的一個 編碼欄位代表的. 你可以用psql的-l選項或 \l命令列出這些編碼.
$ psql -l List of databases Database | Owner | Encoding ---------------+---------+--------------- euc_cn | t-ishii | EUC_CN euc_jp | t-ishii | EUC_JP euc_kr | t-ishii | EUC_KR euc_tw | t-ishii | EUC_TW mule_internal | t-ishii | MULE_INTERNAL regression | t-ishii | SQL_ASCII template1 | t-ishii | EUC_JP test | t-ishii | EUC_JP unicode | t-ishii | UNICODE (9 rows)
PostgreSQL 支援一些編碼 在伺服器和前端之間的自動編碼轉換. 轉換資訊在系統表 pg_conversion 中儲存。 你可以使用 CREATE CONVERSION 建立一個 新的轉換。PostgreSQL帶著一些預定義的轉換。它們在 Table 5-2 中列出.
Table 5-2. Client/Server 字元集編碼
| 伺服器編碼 | 可用客戶端編碼 |
|---|---|
| SQL_ASCII | SQL_ASCII, UNICODE, MULE_INTERNAL |
| EUC_JP | EUC_JP, SJIS, UNICODE, MULE_INTERNAL |
| EUC_CN | EUC_CN, UNICODE, MULE_INTERNAL |
| EUC_KR | EUC_KR, UNICODE, MULE_INTERNAL |
| JOHAB | JOHAB, UNICODE |
| EUC_TW | EUC_TW, BIG5, UNICODE, MULE_INTERNAL |
| LATIN1 | LATIN1, UNICODE, MULE_INTERNAL |
| LATIN2 | LATIN2, WIN1250, UNICODE, MULE_INTERNAL |
| LATIN3 | LATIN3, UNICODE, MULE_INTERNAL |
| LATIN4 | LATIN4, UNICODE, MULE_INTERNAL |
| LATIN5 | LATIN5, UNICODE |
| LATIN6 | LATIN6, UNICODE, MULE_INTERNAL |
| LATIN7 | LATIN7, UNICODE, MULE_INTERNAL |
| LATIN8 | LATIN8, UNICODE, MULE_INTERNAL |
| LATIN9 | LATIN9, UNICODE, MULE_INTERNAL |
| LATIN10 | LATIN10, UNICODE, MULE_INTERNAL |
| ISO_8859_5 | ISO_8859_5, UNICODE, MULE_INTERNAL, WIN, ALT, KOI8 |
| ISO_8859_6 | ISO_8859_6, UNICODE |
| ISO_8859_7 | ISO_8859_7, UNICODE |
| ISO_8859_8 | ISO_8859_8, UNICODE |
| UNICODE | EUC_JP, SJIS, EUC_KR, UHC, JOHAB, EUC_CN, GBK, EUC_TW, BIG5, LATIN1 to LATIN10, ISO_8859_5, ISO_8859_6, ISO_8859_7, ISO_8859_8, WIN, ALT, KOI8, WIN1256, TCVN, WIN874, GB18030, WIN1250 |
| MULE_INTERNAL | EUC_JP, SJIS, EUC_KR, EUC_CN, EUC_TW, BIG5, LATIN1 到 LATIN5, WIN, ALT, WIN1250 BIG5, ISO_8859_5, KOI8 |
| KOI8 | ISO_8859_5, WIN, ALT, KOI8, UNICODE, MULE_INTERNAL |
| WIN | ISO_8859_5, WIN, ALT, KOI8, UNICODE, MULE_INTERNAL |
| ALT | ISO_8859_5, WIN, ALT, KOI8, UNICODE, MULE_INTERNAL |
| WIN1256 | WIN1256, UNICODE |
| TCVN | TCVN, UNICODE |
| WIN874 | WIN874, UNICODE |
要想打開編碼轉換功能,你必須告訴 PostgreSQL 你想在客戶端使用的編碼.你可以用好幾種方法實現這個目的.
用 psql 裡的 \encoding 命令. \encoding 允許你動態修改客戶端編碼. 比如,把編碼改變為 SJIS,輸入:
\encoding SJIS
使用 libpq 函數. \encoding 在做此用途的時候實際上是調用 PQsetClientEncoding().
int PQsetClientEncoding(PGconn *conn, const char *encoding)
這裡 conn 與後端的連結,而 encoding 是你想用的編碼.如果編碼設定成功 它傳回 0,否則傳回 -1.本次連結的目前編碼可以用下面函數顯示:
int PQclientEncoding(const PGconn *conn)
請注意它只傳回編碼 ID,而不是象 EUC_JP 這樣的編碼符號字串. 要把編碼 ID 轉換為編碼符號,你可以用:
char *pg_encoding_to_char(int encoding_id)
使用 SET CLIENT_ENCODING TO. 可以用 SQL 命令設定客戶端編碼:
SET CLIENT_ENCODING TO 'encoding';
你還可以把 SQL92 語法裡的 SET NAMES用於這個目的:
SET NAMES 'encoding';
查詢目前客戶端編碼:
SHOW CLIENT_ENCODING;
傳回預設編碼:
RESET CLIENT_ENCODING;
使用 PGCLIENTENCODING. 如果在客戶端的環境裡定義了 PGCLIENTENCODING 環境變數, 那麼在與伺服器進行連結時將自動選擇客戶端編碼. (這個編碼隨後可以用上面談到的任何其它方法覆蓋.)
使用 client_encoding 變數。 如果在 postgresql.conf 裡設定了 client_encoding 變數, 那麼在與伺服器建立了連結之後,這個客戶端編碼將自動選定。(這個設定隨後可以被上面提到 的其他方法覆蓋。)
假設你選的伺服器編碼是EUC_JP, 客戶端是LATIN1,那麼有些日文字元不能 轉換成LATIN1.這時, 不能用LATIN1字元集表示的字母將被轉換成:
(HEXA DECIMAL)
下面是學習各種類型的編碼系統的好地方.
詳細地解釋了第3.2節出現的EUC_JP, EUC_CN,EUC_KR,EUC_TW.
Unicode 的家目錄.
定義了UTF-8.
Dec 7, 2000 * An automatic encoding translation between Unicode and other encodings are implemented * Changes above will appear in 7.1 May 20, 2000 * SJIS UDC (NEC selection IBM kanji) support contributed by Eiji Tokuya * Changes above will appear in 7.0.1 Mar 22, 2000 * Add new libpq functions PQsetClientEncoding, PQclientEncoding * ./configure --with-mb=EUC_JP now deprecated. use ./configure --enable-multibyte=EUC_JP instead * Add SQL_ASCII regression test case * Add SJIS User Defined Character (UDC) support * All of above will appear in 7.0 July 11, 1999 * Add support for WIN1250 (Windows Czech) as a client encoding (contributed by Pavel Behal) * fix some compiler warnings (contributed by Tomoaki Nishiyama) Mar 23, 1999 * Add support for KOI8(KOI8-R), WIN(CP1251), ALT(CP866) (thanks Oleg Broytmann for testing) * Fix problem with MB and locale Jan 26, 1999 * Add support for Big5 for frontend encoding (you need to create a database with EUC_TW to use Big5) * Add regression test case for EUC_TW (contributed by Jonah Kuo <jonahkuo@mail.ttn.com.tw>) Dec 15, 1998 * Bugs related to SQL_ASCII support fixed Nov 5, 1998 * 6.4 release. In this version, pg_database has "encoding" column that represents the database encoding Jul 22, 1998 * determine encoding at initdb/createdb rather than compile time * support for PGCLIENTENCODING when issuing COPY command * support for SQL92 syntax "SET NAMES" * support for LATIN2-5 * add UNICODE regression test case * new test suite for MB * clean up source files Jun 5, 1998 * add support for the encoding translation between the backend and the frontend * new command SET CLIENT_ENCODING etc. added * add support for LATIN1 character set * enhance 8-bit cleanliness April 21, 1998 some enhancements/fixes * character_length(), position(), substring() are now aware of multi-byte characters * add octet_length() * add --with-mb option to configure * new regression tests for EUC_KR (contributed by Soonmyung Hong) * add some test cases to the EUC_JP regression test * fix problem in regress/regress.sh in case of System V * fix toupper(), tolower() to handle 8bit chars Mar 25, 1998 MB PL2 is incorporated intoPostgreSQL6.3.1 Mar 10, 1998 PL2 released * add regression test for EUC_JP, EUC_CN and MULE_INTERNAL * add an English document (this file) * fix problems concerning 8-bit single byte characters Mar 1, 1998 PL1 released
當你把區域支援打開後,你可以將使用 WIN1250 字元集的 Windows 客戶端與 PostgreSQL 一起用.
請記住下面的東西:
你的成功依賴於合適的系統區域設定.我們已經在 RH6.0 和 Slackware 3.6 上測試過了, 區域設定為 cs_CZ.iso8859-2.
千萬不要把伺服器的資料庫編碼設定為 WIN1250. 只要用 LATIN2 就好了,因為在 Unix 裡沒有 WIN1250 區域.
WIN1250 編碼只用於 Windows ODBC 的客戶端.該字元集是運行時記錄的, 然後才能正確顯示和儲存.
Windows/ODBC 上的 WIN1250
打開 PostgreSQL 的區域支援並把伺服器端 編碼設為 LATIN2.
設定你的安裝,別忘了在你的環境裡建立區域變數. 比如(這些東西對你的環境可能不太正確):
LC_ALL=cs_CZ.ISO8859-2
你必須帶區域集啟動伺服器!
試驗用捷克語,然後用它在查詢裡排序.
在你的 Windows 機器上安裝 PostgreSQL 的 ODBC.
正確地設定你的資料源,在你的 ODBC 配置對話框的 Connect Settings 域裡面 包括這一行:
SET CLIENT_ENCODING = 'WIN1250';
然後再在 Windows 裡用ODBC測試一下.