您的位置:寻梦网首页编程乐园数据库PostgreSQL 7.2 Documentation

5.2. 多字节支持

作者: Tatsuo Ishii , 最后更新:2000-03-22. 参考 Tatsuo 的网站 (http://www.sra.co.jp/people/t-ishii/PostgreSQL/) 获取更多信息.

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

5.2.1. 打开多字节支持

带着多字节选项运行 configure:

./configure --enable-multibyte[
=

encoding_system


]

这里 encoding_system 可以是下表中的一个 值:

Table 5-1. 字符集编码

编码 描述
SQL_ASCII US ASCII
EUC_JP 日文 EUC
EUC_CN 中文 EUC
EUC_KR 韩文 EUC
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

Important: PostgreSQL 7.2 之前, LATIN5 错误地表示 ISO 8859-5 的意思. 从 7.2 开始 LATIN5 表示 ISO8859-9. 如果你有一个在 7.1 或者之前创建的 使用了 LATIN5 的数据库, 而且你希望移植到 7.2(或者以后的版本), 那么你必须非常仔细地 注意这个变化.

Important: 并非所有 API 支持上面列出的编码.比如, PostgreSQL JDBC 驱动就不支持 MULE_INTERNAL LATIN6 LATIN8 LATIN10

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

$ 

./configure --enable-multibyte=EUC_JP

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

5.2.2. 设置编码

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

$ 

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. 服务器和客户端之间的自动编码转换

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_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 MULE_INTERNAL
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
ISO_8859_6 ISO_8859_6 , UNICODE
ISO_8859_7 ISO_8859_7 , UNICODE
ISO_8859_8 ISO_8859_8 , UNICODE
ISO_8859_9 ISO_8859_9 , WIN , ALT , KOI8R , UNICODE , MULE_INTERNAL
UNICODE EUC_JP , SJIS , EUC_KR , EUC_CN , EUC_TW , BIG5 , LATIN1 to LATIN10 , ISO_8859_5 , ISO_8859_6 , ISO_8859_7 , ISO_8859_8 , WIN , ALT , KOI8
MULE_INTERNAL EUC_JP , SJIS , EUC_KR , EUC_CN , EUC_TW , BIG5 , LATIN1 LATIN5 , WIN , ALT , WIN1250
KOI8 ISO_8859_9 , WIN , ALT , KOI8 , UNICODE , MULE_INTERNAL
WIN ISO_8859_9 , WIN , ALT , KOI8 , UNICODE , MULE_INTERNAL
ALT ISO_8859_9 , WIN , ALT , KOI8 , UNICODE , MULE_INTERNAL

要想打开编码转换功能,你必须告诉 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 环境变量, 那么在与服务器进行联接时将自动选择客户端编码. (这个编码随后可以用上面谈到的任何其它方法覆盖.)

5.2.4. 关于 Unicode

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

对于 7.2 而言, --enable-unicode-conversion 不是必须的. 如果声明了 --enable-multibyte ,那么 Unicode 转换功能 是自动打开的.

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

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

(HEXA DECIMAL)

5.2.6. 参考

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

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

详细地解释了第3.2节出现的 EUC_JP EUC_CN EUC_KR EUC_TW

http://www.unicode.org/

Unicode 的家目录.

RFC 2044

定义了 UTF -8.

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 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 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 客户端与 PostgreSQL 一起用.

请记住下面的东西:

  • 你的成功依赖于合适的系统区域设置.我们已经在 RH6.0 Slackware 3.6 上测试过了, 区域设置为 cs_CZ.iso8859-2

  • 千万不要把服务器的数据库编码设置为 WIN1250. 只要用 LATIN2 就好了,因为在 Unix 里没有 WIN1250 区域.

  • WIN1250 编码只用于 Windows ODBC 的客户端.该字符集是运行时记录的, 然后才能正确显示和存储.

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测试一下.