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

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.2 已于 2011 年 12 月结束社区维护,本页译文保留供仍在使用旧版本的读者参考。新系统请看当前版本。

21.2. Character Set Support #

PostgreSQL中的字符集支持允许你以多种字符集 (也称为编码)存储文本,包括 ISO 8859 系列之类的单字节字符集,以及 EUC(扩展 Unix 编码)、UTF-8 和 Mule 内部编 码等多字节字符集。所有受支持的字符集都可以被客户端透明地使用,但其中少 数不支持在服务器内部使用(即不能作为服务器端编码)。默认字符集是在使用 initdb初始化PostgreSQL 数据库集簇时选定的。创建数据库时可以覆盖该设置,因此你可以拥有多个数据 库,并让每个数据库使用不同的字符集。

21.2.1. 支持的字符集 #

表 21.1显示了PostgreSQL中可用的字符集。

表 21.1. PostgreSQL 字符集

名称 描述 语言 是否服务器端? 字节数/字符 别名
BIG5 Big Five 繁体中文 否 1-2 WIN950, Windows950
EUC_CN 扩展 Unix 编码-CN 简体中文 是 1-3  
EUC_JP 扩展 Unix 编码-JP 日语 是 1-3  
EUC_KR 扩展 Unix 编码-KR 韩语 是 1-3  
EUC_TW 扩展 Unix 编码-TW 繁体中文、台湾语 是 1-3  
GB18030 国家标准 中文 否 1-4  
GBK 扩展国家标准 简体中文 否 1-2 WIN936, Windows936
ISO_8859_5 ISO 8859-5, ECMA 113 拉丁语/西里尔语 是 1  
ISO_8859_6 ISO 8859-6, ECMA 114 拉丁语/阿拉伯语 是 1  
ISO_8859_7 ISO 8859-7, ECMA 118 拉丁语/希腊语 是 1  
ISO_8859_8 ISO 8859-8, ECMA 121 拉丁语/希伯来语 是 1  
JOHAB JOHAB 韩语 否 1-3  
KOI8 KOI8-R(U) 西里尔语 是 1 KOI8R
LATIN1 ISO 8859-1, ECMA 94 西欧 是 1 ISO88591
LATIN2 ISO 8859-2, ECMA 94 中欧 是 1 ISO88592
LATIN3 ISO 8859-3, ECMA 94 南欧 是 1 ISO88593
LATIN4 ISO 8859-4, ECMA 94 北欧 是 1 ISO88594
LATIN5 ISO 8859-9, ECMA 128 土耳其语 是 1 ISO88599
LATIN6 ISO 8859-10, ECMA 144 北欧 是 1 ISO885910
LATIN7 ISO 8859-13 波罗的海 是 1 ISO885913
LATIN8 ISO 8859-14 凯尔特语 是 1 ISO885914
LATIN9 ISO 8859-15 带欧元符号和重音字符的 LATIN1 是 1 ISO885915
LATIN10 ISO 8859-16, ASRO SR 14111 罗马尼亚语 是 1 ISO885916
MULE_INTERNAL Mule 内部编码 多语种 Emacs 是 1-4  
SJIS Shift JIS 日语 否 1-2 Mskanji, ShiftJIS, WIN932, Windows932
SQL_ASCII 未指定(见正文) 任意 是 1  
UHC 统一韩语编码 韩语 否 1-2 WIN949, Windows949
UTF8 Unicode,8 位 所有 是 1-4 Unicode
WIN866 Windows CP866 西里尔语 是 1 ALT
WIN874 Windows CP874 泰语 是 1  
WIN1250 Windows CP1250 中欧 是 1  
WIN1251 Windows CP1251 西里尔语 是 1 WIN
WIN1252 Windows CP1252 西欧 是 1  
WIN1253 Windows CP1253 希腊语 是 1  
WIN1254 Windows CP1254 土耳其语 是 1  
WIN1255 Windows CP1255 希伯来语 是 1  
WIN1256 Windows CP1256 阿拉伯语 是 1  
WIN1257 Windows CP1257 波罗的海 是 1  
WIN1258 Windows CP1258 越南语 是 1 ABC, TCVN, TCVN5712, VSCII

并非所有客户端API都支持上表中的全部字符集。例如, PostgreSQL JDBC 驱动就不支持 MULE_INTERNAL、LATIN6、 LATIN8和LATIN10。

SQL_ASCII 设置的行为与其他设置有很大不同。当服务器字符集为 SQL_ASCII 时,服务器按 ASCII 标准解释字节值 0-127,而将字节值 128-255 视为不作解释的字符。设置为 SQL_ASCII 时,不会进行任何编码转换。因此,这一设置与其说是声明使用某种特定编码,不如说是声明不关心编码。在大多数情况下,如果需要处理任何非 ASCII 数据,使用 SQL_ASCII 都是不明智的,因为 PostgreSQL 将无法帮助转换或验证非 ASCII 字符。

21.2.2. 设置字符集

initdb为PostgreSQL集 簇定义默认字符集(编码)。例如:

initdb -E EUC_JP

这会把默认字符集设为EUC_JP(日语的扩展 Unix 编 码)。如果你喜欢更长的选项形式,也可以用--encoding代 替-E。如果既没有给出-E也没有给出 --encoding,initdb会根据指定的 或默认的区域设置,尝试确定应使用的合适编码。

你可以创建一个使用不同字符集的数据库:

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
 postgres      | t-ishii | EUC_JP
 regression    | t-ishii | SQL_ASCII
 template1     | t-ishii | EUC_JP
 test          | t-ishii | EUC_JP
 utf8          | t-ishii | UTF8
(9 rows)

重要

尽管你可以为数据库指定任意编码,但选择一种与所选区域设置的期望不相符 的编码是不明智的。LC_COLLATE和 LC_CTYPE设置隐含着一种特定的编码,区域设置相关的 操作(例如排序)很可能会错误解释以不兼容编码存储的数据。

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

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

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

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

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

服务器字符集 可用的客户端字符集
BIG5 不支持作为服务器编码
EUC_CN EUC_CN, MULE_INTERNAL, UTF8
EUC_JP EUC_JP, MULE_INTERNAL, SJIS, UTF8
EUC_KR EUC_KR, MULE_INTERNAL, UTF8
EUC_TW EUC_TW, BIG5, MULE_INTERNAL, UTF8
GB18030 不支持用作服务器编码
GBK 不支持作为服务器编码
ISO_8859_5 ISO_8859_5, KOI8R, MULE_INTERNAL, UTF8, WIN866, WIN1251
ISO_8859_6 ISO_8859_6, UTF8
ISO_8859_7 ISO_8859_7, UTF8
ISO_8859_8 ISO_8859_8, UTF8
JOHAB JOHAB, UTF8
KOI8 KOI8, ISO_8859_5, MULE_INTERNAL, UTF8, WIN866, WIN1251
LATIN1 LATIN1, MULE_INTERNAL, UTF8
LATIN2 LATIN2, MULE_INTERNAL, UTF8, WIN1250
LATIN3 LATIN3, MULE_INTERNAL, UTF8
LATIN4 LATIN4, MULE_INTERNAL, UTF8
LATIN5 LATIN5, UTF8
LATIN6 LATIN6, UTF8
LATIN7 LATIN7, UTF8
LATIN8 LATIN8, UTF8
LATIN9 LATIN9, UTF8
LATIN10 LATIN10, UTF8
MULE_INTERNAL MULE_INTERNAL, BIG5, EUC_CN, EUC_JP, EUC_KR, EUC_TW, ISO_8859_5, KOI8R, LATIN1 to LATIN4, SJIS, WIN866, WIN1250, WIN1251
SJIS 不支持用作服务器编码
SQL_ASCII 任意(不执行转换)
UHC 不支持作为服务器编码
UTF8 all supported encodings
WIN866 WIN866, ISO_8859_5, KOI8R, MULE_INTERNAL, UTF8, WIN1251
WIN874 WIN874, UTF8
WIN1250 WIN1250, LATIN2, MULE_INTERNAL, UTF8
WIN1251 WIN1251, ISO_8859_5, KOI8R, MULE_INTERNAL, UTF8, WIN866
WIN1252 WIN1252, UTF8
WIN1253 WIN1253, UTF8
WIN1254 WIN1254, UTF8
WIN1255 WIN1255, UTF8
WIN1256 WIN1256, UTF8
WIN1257 WIN1257, UTF8
WIN1258 WIN1258, UTF8

若要启用自动字符集转换,必须告诉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中没有表示形式的日语字符, 就会出现错误。

如果客户端字符集定义为 SQL_ASCII,则无论服务器字符集是什么,都会禁用编码转换。与服务器一样,除非处理的全部是 ASCII 数据,否则使用 SQL_ASCII 是不明智的。

21.2.4. 进一步阅读

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

http://www.i18ngurus.com/docs/984813247.html

一份关于字符集、编码和代码页的大量文档合集。

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 3629

这里定义了UTF-8(8 位 UCS/Unicode 转换格式)。

提交更正

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