5.2. 多字節支援

作者: 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 起,多字節支援就是預設的了。

5.2.1. 支援字元集編碼

下面的字元集可以用做資料庫編碼。

Table 5-1. 字元集編碼

編碼描述
SQL_ASCIIUS ASCII
EUC_JP日文 EUC
EUC_CN中文 EUC
EUC_KR韓文 EUC
JOHAB韓文 EUC (Hangle base)
EUC_TW台灣 EUC
UNICODEUnicode(UTF-8)
MULE_INTERNALMule 內部編碼
LATIN1ISO 8859-1 ECMA-94 Latin Alphabet No.1
LATIN2ISO 8859-2 ECMA-94 Latin Alphabet No.2
LATIN3ISO 8859-3 ECMA-94 Latin Alphabet No.3
LATIN4ISO 8859-4 ECMA-94 Latin Alphabet No.4
LATIN5ISO 8859-9 ECMA-128 Latin Alphabet No.5
LATIN6ISO 8859-10 ECMA-144 Latin Alphabet No.6
LATIN7ISO 8859-13 Latin Alphabet No.7
LATIN8ISO 8859-14 Latin Alphabet No.8
LATIN9ISO 8859-15 Latin Alphabet No.9
LATIN10ISO 8859-16 ASRO SR 14111 Latin Alphabet No.10
ISO-8859-5ECMA-113 Latin/Cyrillic
ISO-8859-6ECMA-114 Latin/Arabic
ISO-8859-7ECMA-118 Latin/Greek
ISO-8859-8ECMA-121 Latin/Hebrew
KOI8KOI8-R(U)
WINWindows CP1251
ALTWindows 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_INTERNALLATIN6LATIN8LATIN10

5.2.2. 設定編碼

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)

5.2.3. 伺服器和客戶端之間的自動編碼轉換

PostgreSQL 支援一些編碼 在伺服器和前端之間的自動編碼轉換. 轉換資訊在系統表 pg_conversion 中儲存。 你可以使用 CREATE CONVERSION 建立一個 新的轉換。PostgreSQL帶著一些預定義的轉換。它們在 Table 5-2 中列出.

Table 5-2. Client/Server 字元集編碼

伺服器編碼可用客戶端編碼
SQL_ASCIISQL_ASCII, UNICODE, MULE_INTERNAL
EUC_JPEUC_JP, SJIS, UNICODE, MULE_INTERNAL
EUC_CNEUC_CN, UNICODE, MULE_INTERNAL
EUC_KREUC_KR, UNICODE, MULE_INTERNAL
JOHABJOHAB, UNICODE
EUC_TWEUC_TW, BIG5, UNICODE, MULE_INTERNAL
LATIN1LATIN1, UNICODE, MULE_INTERNAL
LATIN2LATIN2, WIN1250, UNICODE, MULE_INTERNAL
LATIN3LATIN3, UNICODE, MULE_INTERNAL
LATIN4LATIN4, UNICODE, MULE_INTERNAL
LATIN5LATIN5, UNICODE
LATIN6LATIN6, UNICODE, MULE_INTERNAL
LATIN7LATIN7, UNICODE, MULE_INTERNAL
LATIN8LATIN8, UNICODE, MULE_INTERNAL
LATIN9LATIN9, UNICODE, MULE_INTERNAL
LATIN10LATIN10, UNICODE, MULE_INTERNAL
ISO_8859_5ISO_8859_5, UNICODE, MULE_INTERNAL, WIN, ALT, KOI8
ISO_8859_6ISO_8859_6, UNICODE
ISO_8859_7ISO_8859_7, UNICODE
ISO_8859_8ISO_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_INTERNALEUC_JP, SJIS, EUC_KR, EUC_CN, EUC_TW, BIG5, LATIN1LATIN5, WIN, ALT, WIN1250 BIG5, ISO_8859_5, KOI8
KOI8ISO_8859_5, WIN, ALT, KOI8, UNICODE, MULE_INTERNAL
WINISO_8859_5, WIN, ALT, KOI8, UNICODE, MULE_INTERNAL
ALTISO_8859_5, WIN, ALT, KOI8, UNICODE, MULE_INTERNAL
WIN1256WIN1256, UNICODE
TCVNTCVN, UNICODE
WIN874WIN874, UNICODE

要想打開編碼轉換功能,你必須告訴 PostgreSQL 你想在客戶端使用的編碼.你可以用好幾種方法實現這個目的.

5.2.4. 如果不能轉換會怎樣?

假設你選的伺服器編碼是EUC_JP, 客戶端是LATIN1,那麼有些日文字元不能 轉換成LATIN1.這時, 不能用LATIN1字元集表示的字母將被轉換成:

(HEXA DECIMAL)

5.2.5. 參考

下面是學習各種類型的編碼系統的好地方.

ftp://ftp.ora.com/pub/examples/nutshell/ujip/doc/cjk.inf

詳細地解釋了第3.2節出現的EUC_JPEUC_CNEUC_KREUC_TW

http://www.unicode.org/

Unicode 的家目錄.

RFC 2044

定義了UTF-8.

5.2.6. 歷史

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 )

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

5.2.7. Windows/ODBC 裡的 WIN1250

當你把區域支援打開後,你可以將使用 WIN1250 字元集的 Windows 客戶端與 PostgreSQL 一起用.

請記住下面的東西:

Windows/ODBC 上的 WIN1250

  1. 打開 PostgreSQL 的區域支援並把伺服器端 編碼設為 LATIN2

  2. 設定你的安裝,別忘了在你的環境裡建立區域變數. 比如(這些東西對你的環境可能不太正確):

    LC_ALL=cs_CZ.ISO8859-2

  3. 你必須帶區域集啟動伺服器!

  4. 試驗用捷克語,然後用它在查詢裡排序.

  5. 在你的 Windows 機器上安裝 PostgreSQL 的 ODBC.

  6. 正確地設定你的資料源,在你的 ODBC 配置對話框的 Connect Settings 域裡面 包括這一行:

    SET CLIENT_ENCODING = 'WIN1250';

  7. 然後再在 Windows 裡用ODBC測試一下.