5.2. 多字节支持

作者: Tatsuo Ishii, 最后更新:2000-03-22. 参考 Tatsuo 的 网站 获取更多信息.

多字节支持 (MB)是为了让 Postgres 能够处理多字节字符集,比如 EUC (扩展 Unix 编码 Extended Unix Code),Unicode 和 Mule 国际编码.把 MB 打开,你就能在正则表达式(regexp) LIKE,和一些其它函数里使用多字节字符集了. 缺省的编码系统是在你用 initdb 初始化 Postgres 系统安装的时候 确立的.请注意这个缺省是可以在使用 createdb 或者 SQL 命令 CREATE DATABASE 创建数据库的时候覆盖的.所以你可以拥有多个有着不同编码系统的数据库.

MB 同时还修补了一些与 8 位单字符集相关的问题,其中 包括ISO8859.(我不敢说我修补了所有问题.我只能说有了这个补丁以后 蜕变测试运行得很好,而且还可以使用几个法文字符.如果你在使用 8-位字符碰到任何问题,请告诉我.)

5.2.1. 打开 MB

带着多字节选项运行 configure:

% ./configure --enable-multibyte[=encoding_system]
     
这里 encoding_system 可以是下表中的一个 值:

Table 5-1. Postgres 字符集编码

编码描述
SQL_ASCIIASCII
EUC_JP日文 EUC
EUC_CN中文 EUC
EUC_KR韩文 EUC
EUC_TW台湾 EUC
UNICODEUnicode(UTF-8)
MULE_INTERNALMule 国际编码
LATIN1ISO 8859-1 英文及一些欧洲语言
LATIN2ISO 8859-2 英文及一些欧洲语言
LATIN3ISO 8859-3 英文及一些欧洲语言
LATIN4ISO 8859-4 英文及一些欧洲语言
LATIN5ISO 8859-5 英文及一些欧洲语言
KOI8KOI8-R
WINWindows CP1251
ALTWindows CP866

下面是一个配置例子,把 Postgres 配置为缺省为日文编码:

% ./configure --enable-multibyte=EUC_JP
     

如果忽略编码系统(./configure --enable-multibyte), 那么假设为 SQL_ASCII.

5.2.2. 设置编码

initdb 为一次 Postgres 安装定义缺省的编码系统,比如:

% initdb -E EUC_JP
     
把缺省编码设置为 EUC_JP(用于日文的扩展的 Unix 编码). 如果你喜欢用长选项声明的话,你可以用 "--encoding" 代替 "-E". 如果没有给出 -E 或者 --encoding 选项,则使用在编译时声明的 编码.

你可以创建一个有着不同编码的数据库:

% 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. 前后端之间的自动编码转换

Postgres 支持一些编码 后端之间的自动编码转换.

Table 5-2. Postgres Client/Server 字符集编码

服务器编码可用客户端编码
EUC_JPEUC_JP, SJIS
EUC_TWEUC_TW, BIG5
LATIN2LATIN2, WIN1250
LATIN5LATIN5, WIN, ALT
MULE_INTERNALEUC_JP, SJIS, EUC_KR, EUC_CN, EUC_TW, BIG5, LATIN1 to LATIN5, WIN, ALT, WIN1250

要想打开编码转换功能,你必须告诉 Postgres 你想在前端使用的编码.你可以用好几种方法实现这个目的.

5.2.4. 关于 Unicode

自 7.1 起开始 PostgreSQL 支持 Unicode 和其它编码之间的自动转换 .因为它需要巨大的转换表,所以缺省时是没有打开的. 要打开这个特性,带着 --enable-unicode-conversion 选项运行 configure.请注意它也要求使用 --enable-multibyte 选项.

5.2.5. 如果不能转换会怎样?

假设你的后端的编码是 EUC_JP,前端是 LATIN1,那么有些日文字符不能 转换成 LATIN1.这时,不能用 LATIN1 字符集表示的字母将被转换成:

(HEXA DECIMAL)
     

5.2.6. 参考

下面是学习各种类型的编码系统的好地方.

5.2.7. 历史

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 fronend 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 cleaness

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 into PostgreSQL 6.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.8. Windows/ODBC 里的 WIN1250

当你把区域支持打开后,你可以将使用 WIN1250 字符集的 Windows 客户端与 Postgres 一起用.

请记住下面的东西:

运行时,请记住下面几样事情(很重要!!):

Windows/ODBC 上的 WIN1250

  1. 打开 Postgres 的区域支持并把多字节 编码设为 LATIN2

  2. 设置你的安装,别忘了在你的 profile (环境)里创建区域变量. 比如(这些东西对你的环境可能不太正确):

    LC_ALL=cs_CZ.ISO8859-2
    LC_COLLATE=cs_CZ.ISO8859-2
    LC_CTYPE=cs_CZ.ISO8859-2
    LC_MONETARY=cs_CZ.ISO8859-2
    LC_NUMERIC=cs_CZ.ISO8859-2
    LC_TIME=cs_CZ.ISO8859-2
           

  3. 你必须带区域集启动 postmaster!

  4. 试验用捷克语,然后用它在查询里排序.

  5. 在你的 M$ Windows 机器上安装 PgSQL 的 ODBC.

  6. 正确地设置你的数据源,在你的 ODBC 配置对话框的 Connect Settings 域里面 包括这一行:

    SET CLIENT_ENCODING = 'WIN1250';
           

  7. 然后再在 Windows 里用ODBC测试一下.