↑↓ 选择 ↵ 打开 ⌫ 改范围 完整检索页

pgsql.cc 提供对 postgresql.org 官网内容的中文翻译,由 Pigsty 团队维护。

受支持版本: 当前版本 (18) / 17 / 16 / 15 / 14
测试与开发版本: 19 / devel
不受支持的版本: 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 8.0 已于 2010 年 10 月结束社区维护,本页译文保留供仍在使用旧版本的读者参考。新系统请看当前版本。

20.2. 字符集支持 #

PostgreSQL中的字符集支持允许你以多种字符集 存储文本,包括 ISO 8859 系列之类的单字节字符集,以及 EUC(扩展 Unix 编码)、Unicode 和 Mule 内部编 码之类的多字节字符集。所有字符集都可以在整个服务器中透明地使用。 (如果你使用来自其他来源的扩展函数,则取决于它们的代码编写得是否 正确。)默认字符集是在使用 initdb初始化PostgreSQL 数据库集簇时选定的。在使用createdb创建数据库时, 或者使用 SQL 命令CREATE DATABASE时,都可以覆盖 该设置,因此你可以拥有多个 数据库,并让每个数据库使用不同的字符集。

20.2.1. 支持的字符集 #

表 20.1显示了服务器中可用的字符集。

表 20.1. 服务器字符集

名称 描述
SQL_ASCII ASCII
EUC_JP 日语 EUC
EUC_CN 中文 EUC
EUC_KR 韩语 EUC
JOHAB 韩语 EUC(Hangle 基)
EUC_TW 台湾 EUC
UNICODE Unicode(UTF-8)
MULE_INTERNAL Mule 内部编码
LATIN1 ISO 8859-1/ECMA 94(拉丁字母表 1 号)
LATIN2 ISO 8859-2/ECMA 94(拉丁字母表 2 号)
LATIN3 ISO 8859-3/ECMA 94(拉丁字母表 3 号)
LATIN4 ISO 8859-4/ECMA 94(拉丁字母表 4 号)
LATIN5 ISO 8859-9/ECMA 128(拉丁字母表 5 号)
LATIN6 ISO 8859-10/ECMA 144(拉丁字母表 6 号)
LATIN7 ISO 8859-13(拉丁字母表 7 号)
LATIN8 ISO 8859-14(拉丁字母表 8 号)
LATIN9 ISO 8859-15(拉丁字母表 9 号)
LATIN10 ISO 8859-16/ASRO SR 14111(拉丁字母表 10 号)
ISO_8859_5 ISO 8859-5/ECMA 113(拉丁/西里尔)
ISO_8859_6 ISO 8859-6/ECMA 114(拉丁/阿拉伯)
ISO_8859_7 ISO 8859-7/ECMA 118(拉丁/希腊)
ISO_8859_8 ISO 8859-8/ECMA 121(拉丁/希伯来)
KOI8 KOI8-R(U)
ALT Windows CP866
WIN874 Windows CP874(泰语)
WIN1250 Windows CP1250
WIN Windows CP1251
WIN1256 Windows CP1256(阿拉伯语)
TCVN TCVN-5712/Windows CP1258(越南语)

重要

在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。

20.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)

重要

虽然你可以为数据库指定任何想要的编码,但选择一个与所选区域设置 所期望的编码不一致的编码是不明智的。LC_COLLATE和 LC_CTYPE设置隐含着一种特定的编码,依赖区域的 操作(例如排序)很可能会错误解释以不兼容编码存储的数据。

由于这些区域设置被initdb冻结,在同一集簇的不同 数据库中使用不同编码的表面灵活性,与其说是真实的,不如说是理论上的。 这些机制将来很可能会在 PostgreSQL的 未来版本中被重新考虑。

安全使用多种编码的一种办法,是在initdb时把区域 设置设为C或POSIX,从而禁用 任何真正的区域感知。

20.2.3. 服务器和客户端之间的自动字符集转换

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

表 20.2. 客户端/服务器字符集转换

服务器字符集 可用的客户端字符集
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 到 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
ALT ISO_8859_5, WIN, ALT, KOI8, UNICODE, MULE_INTERNAL
WIN874 WIN874, UNICODE
WIN1250 LATIN2, WIN1250, UNICODE, MULE_INTERNAL
WIN ISO_8859_5, WIN, ALT, KOI8, UNICODE, MULE_INTERNAL
WIN1256 WIN1256, UNICODE
TCVN TCVN, 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 'value';
    

    也可以为此使用更标准的 SQL 语法SET NAMES:

    SET NAMES 'value';
    

    要查询当前客户端编码:

    SHOW client_encoding;
    

    要返回到默认编码:

    RESET client_encoding;
    
  • 使用PGCLIENTENCODING。如果在客户端环境中定义了 PGCLIENTENCODING环境变量,那么连接服务器时会自动选 择该客户端编码。(之后仍可以用上面提到的任何其他方法覆盖它。)

  • 使用配置变量client_encoding。如果设置了 client_encoding变量,那么连接服务器时会自动选 择该客户端编码。(之后仍可以用上面提到的任何其他方法覆盖它。)

如果某个特定字符无法完成转换——假设你为服务器选择了 EUC_JP,而为客户端选择了LATIN1, 那么某些日语字符将无法转换为LATIN1—— 此时该字符会被转换为带括号的十六进制字节值,例如 (826C)。

20.2.4. 进一步阅读

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

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 在这里定义。

提交更正

译文有误、术语不当或页面显示问题,请到译文仓库 pgsty/pgdoc 报告译文问题。 英文原文本身的问题,请在当前版本的对应页面向上游反馈;上游不再修订已结束维护的版本。