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