↑↓ 选择↵ 打开⌫ 切换范围完整搜索

PG.CENTER 连接 PostgreSQL 文档、百科与生态知识。由 Pigsty 维护。

支持中的版本: 当前版本 (18) / 17 / 16 / 15 / 14
开发中的版本: 19 / 20devel
已结束支持的版本: 13 / 12 / 11 / 10 / 9.6 / 9.5 / 9.4 / 9.3 / 9.2 / 9.1 / 9.0 / 8.4 / 8.3 / 8.2 / 8.1 / 8.0 / 7.4 / 7.3 / 7.2 / 7.1
历史版本。 PostgreSQL 7.3 已结束支持。 请参阅 当前版本手册.

7.2. 多字节支持 #

作者

Tatsuo Ishii(),最后更新于 2002-07-24。更多信息请查看Tatsuo 的网站。

多字节(MB)支持旨在让 PostgreSQL能够处理多字节字符集,例如EUC(扩展 Unix 编码)、Unicode 和 Mule 内部编码。启用MB后,你可以在正则表达式(regexp)、LIKE 以及其他一些函数中使用多字节字符集。默认编码系统是在使用initdb初始化 PostgreSQL安装时选定的。注意,这可以在你使用createdb创建数据库或使用 SQL 命令 CREATE DATABASE时被覆盖。因此你可以拥有多个数据库,并让每个数据库使用不同的编码系统。注意MB也能处理单字节字符集,例如 ISO-8859-1。

从 PostgreSQL 7.3 版开始,默认启用多字节支持。

7.2.1. 支持的字符集编码

下列编码可以用作数据库编码。

表 7.1. 字符集编码

编码描述
SQL_ASCIIASCII
EUC_JP日语 EUC
EUC_CN中文 EUC
EUC_KR韩语 EUC
JOHAB韩语 EUC(基于韩文字母)
EUC_TW台湾 EUC
UNICODEUnicode(UTF-8)
MULE_INTERNALMule 内部编码
LATIN1ISO 8859-1 ECMA-94 拉丁字母 No.1
LATIN2ISO 8859-2 ECMA-94 拉丁字母 No.2
LATIN3ISO 8859-3 ECMA-94 拉丁字母 No.3
LATIN4ISO 8859-4 ECMA-94 拉丁字母 No.4
LATIN5ISO 8859-9 ECMA-128 拉丁字母 No.5
LATIN6ISO 8859-10 ECMA-144 拉丁字母 No.6
LATIN7ISO 8859-13 拉丁字母 No.7
LATIN8ISO 8859-14 拉丁字母 No.8
LATIN9ISO 8859-15 拉丁字母 No.9
LATIN10ISO 8859-16 ASRO SR 14111 拉丁字母 No.10
ISO-8859-5ECMA-113 拉丁/西里尔
ISO-8859-6ECMA-114 拉丁/阿拉伯
ISO-8859-7ECMA-118 拉丁/希腊
ISO-8859-8ECMA-121 拉丁/希伯来
KOI8KOI8-R(U)
WINWindows CP1251
ALTWindows CP866
WIN1256阿拉伯语 Windows CP1256
TCVN越南语 TCVN-5712(Windows CP1258)
WIN874泰语 Windows CP874


重要

在PostgreSQL 7.2 之前,LATIN5错误地表示 ISO 8859-5。从 7.2 开始,LATIN5表示 ISO 8859-9。如果你有一个在 7.1 或更早版本上创建的LATIN5数据库,并且想迁移到 7.2(或更高版本),就应该非常小心这个变化。

重要

并非所有API都支持上面列出的编码。例如,PostgreSQL的 JDBC 驱动不支持 MULE_INTERNAL、LATIN6、LATIN8和LATIN10。

7.2.2. 设置编码

initdb为PostgreSQL 安装定义默认编码。例如:

$ initdb -E EUC_JP

这会把默认编码设为EUC_JP(日语的扩展 Unix 编码)。注意,如果你喜欢较长的选项形式,也可以用--encoding代替-E。如果既没有给出-E也没有给出 --encoding,就使用 SQL_ASCII。

你可以创建使用不同编码的数据库:

$ createdb -E EUC_KR korean

这会创建一个名为korean的数据库,使用 EUC_KR编码。另一种实现方式是使用 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)

7.2.3. 服务器和客户端之间的自动编码转换

对于某些编码,PostgreSQL支持在服务器和客户端之间进行自动编码转换。转换信息保存在pg_conversion系统目录中。可以使用CREATE CONVERSION命令创建新的转换。PostgreSQL自带一些预定义转换,它们列在表 7.2中。

表 7.2. 客户端/服务器字符集编码

服务器编码可用的客户端编码
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, LATIN1 to LATIN5, 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 你希望客户端使用哪种编码。有几种方法可以做到这一点。

  • 在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变量,那么连接服务器时会自动选择该客户端编码。(之后仍可以用上面提到的任何其他方法覆盖它。)

7.2.4. 如果无法完成转换会怎样?

假设你为服务器选择了EUC_JP,为客户端选择了LATIN1,那么某些日语字符无法翻译为LATIN1。在这种情况下,无法用LATIN1字符集表示的字母会被变换为:

(HEXA DECIMAL)

7.2.5. 参考资料

这些都是开始了解各种编码系统的良好资料。

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

对EUC_JP、EUC_CN、EUC_KR、EUC_TW的详细说明见 3.2 节。

http://www.unicode.org/

Unicode Consortium 的网站

RFC 2044

UTF-8 在这里定义。

7.2.6. 历史

Dec 7, 2000
	* 实现了 Unicode 与其他编码之间的自动编码转换
	* 以上变更将出现在 7.1 中

May 20, 2000
	* SJIS UDC(NEC 选定 IBM 汉字)支持,由 Eiji Tokuya 贡献
	* 以上变更将出现在 7.0.1 中

Mar 22, 2000
	* 新增 libpq 函数 PQsetClientEncoding、PQclientEncoding
	* ./configure --with-mb=EUC_JP
	  已废弃。请改用 ./configure --enable-multibyte=EUC_JP
   	* 新增 SQL_ASCII 回归测试用例
	* 新增 SJIS 用户自定义字符(UDC)支持
	* 以上全部将出现在 7.0 中

July 11, 1999
	* 新增对 WIN1250(Windows 捷克语)作为客户端编码的支持(由 Pavel Behal 贡献)
	* 修复一些编译器警告(由 Tomoaki Nishiyama 贡献)

Mar 23, 1999
	* 新增对 KOI8(KOI8-R)、WIN(CP1251)、ALT(CP866) 的支持(感谢 Oleg Broytmann 测试)
	* 修复 MB 与 locale 相关的问题

Jan 26, 1999
	* 新增 Big5 作为前端编码的支持(要使用 Big5,需用 EUC_TW 创建数据库)
	* 新增 EUC_TW 的回归测试用例(由 Jonah Kuo )

Dec 15, 1998
	* 修复了与 SQL_ASCII 支持相关的一些错误

Nov 5, 1998
	* 6.4 发布。此版本中,pg_database 增加了表示数据库编码的 "encoding" 列

Jul 22, 1998
	* 在 initdb/createdb 时确定编码,而非编译时
	* 在发出 COPY 命令时支持 PGCLIENTENCODING
	* 支持 SQL92 语法 "SET NAMES"
	* 支持 LATIN2-5
	* 新增 UNICODE 回归测试用例
	* 新的 MB 测试套件
	* 清理源代码文件

Jun 5, 1998
	* 新增后端与前端之间的编码转换支持
	* 新增 SET CLIENT_ENCODING 等新命令
	* 新增 LATIN1 字符集支持
	* 增强 8 位洁净性

April 21, 1998 一些增强/修复
	* character_length()、position()、substring() 现在能识别多字节字符
	* 新增 octet_length()
	* 为 configure 新增 --with-mb 选项
	* 新的 EUC_KR 回归测试(由 Soonmyung Hong 贡献)
	* 为 EUC_JP 回归测试新增一些测试用例
	* 修复 System V 情况下 regress/regress.sh 中的问题
	* 修复 toupper()、tolower() 以处理 8 位字符

Mar 25, 1998 MB PL2 被并入 PostgreSQL 6.3.1

Mar 10, 1998 PL2 发布
	* 为 EUC_JP、EUC_CN 和 MULE_INTERNAL 新增回归测试
	* 新增一份英文文档(本文件)
	* 修复与 8 位单字节字符有关的问题

Mar 1, 1998 PL1 发布

7.2.7. Windows/ODBC 上的 WIN1250

Windows 客户端平台上的 WIN1250 字符集可以配合启用了区域支持的 PostgreSQL使用。

应记住以下几点:

  • 成功与否取决于正确的系统区域设置。这已经在Red Hat 6.0和Slackware 3.6上用 cs_CZ.iso8859-2区域测试过。

  • 决不要尝试把服务器的数据库编码设为 WIN1250。始终改用 LATIN2,因为 Unix 中没有 WIN1250 区域。

  • WIN1250 编码只对 Windows ODBC 客户端可用。字符会被动态转码,以便正确显示和存回。

Windows/ODBC 上的 WIN1250

  1. 在启用区域支持、服务器端编码设为LATIN2的情况下编译 PostgreSQL。

  2. 设置你的安装。不要忘记在环境中创建区域变量。例如(这可能不适用于你的环境):

    LC_ALL=cs_CZ.ISO8859-2

  3. 必须带着区域设置启动服务器!

  4. 用捷克语试一试,并在查询上进行排序。

  5. 在你的 Windows 机器上为PostgreSQL安装 ODBC 驱动。

  6. 正确设置你的数据源。在 ODBC 配置对话框的Connect Settings字段中加入这一行:

    SET CLIENT_ENCODING = 'WIN1250';

  7. 现在再试一次,但这次是在带 ODBC 的 Windows 中。

报告文档问题

阅读 上游文档. 反馈更正前请先核对 当前版本手册.