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

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 9.4 已结束支持。 2020-02-13. 请参阅 当前版本手册.

22.3. 字符集支持 #

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

不过,一项重要限制是,每个数据库的字符集必须与数据库的 LC_CTYPE(字符分类)和 LC_COLLATE(字符串排序顺序)区域设置兼容。对于 C 或 POSIX 区域设置,允许使用任何字符集;对于其他区域设置,只有一种字符集能够正确工作。(但在 Windows 上,UTF-8 编码可以与任何区域设置一起使用。)

22.3.1. 支持的字符集 #

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

表 22.1. PostgreSQL 字符集

名称描述语言是否服务器端?字节数/字符别名
BIG5Big Five繁体中文否1-2WIN950, Windows950
EUC_CN扩展 Unix 编码-CN简体中文是1-3 
EUC_JP扩展 Unix 编码-JP日语是1-3 
EUC_JIS_2004扩展 Unix 编码-JP,JIS X 0213日语是1-3 
EUC_KR扩展 Unix 编码-KR韩语是1-3 
EUC_TW扩展 Unix 编码-TW繁体中文、台湾语是1-3 
GB18030国家标准中文否1-4 
GBK扩展国家标准简体中文否1-2WIN936, Windows936
ISO_8859_5ISO 8859-5, ECMA 113拉丁语/西里尔语是1 
ISO_8859_6ISO 8859-6, ECMA 114拉丁语/阿拉伯语是1 
ISO_8859_7ISO 8859-7, ECMA 118拉丁语/希腊语是1 
ISO_8859_8ISO 8859-8, ECMA 121拉丁语/希伯来语是1 
JOHABJOHAB韩语否1-3 
KOI8RKOI8-R西里尔语(俄语)是1KOI8
KOI8UKOI8-U西里尔语(乌克兰语)是1 
LATIN1ISO 8859-1, ECMA 94西欧是1ISO88591
LATIN2ISO 8859-2, ECMA 94中欧是1ISO88592
LATIN3ISO 8859-3, ECMA 94南欧是1ISO88593
LATIN4ISO 8859-4, ECMA 94北欧是1ISO88594
LATIN5ISO 8859-9, ECMA 128土耳其语是1ISO88599
LATIN6ISO 8859-10, ECMA 144北欧是1ISO885910
LATIN7ISO 8859-13波罗的海是1ISO885913
LATIN8ISO 8859-14凯尔特语是1ISO885914
LATIN9ISO 8859-15带欧元符号和重音字符的 LATIN1是1ISO885915
LATIN10ISO 8859-16, ASRO SR 14111罗马尼亚语是1ISO885916
MULE_INTERNALMule 内部编码多语种 Emacs是1-4 
SJISShift JIS日语否1-2Mskanji, ShiftJIS, WIN932, Windows932
SHIFT_JIS_2004Shift JIS, JIS X 0213日语否1-2 
SQL_ASCII未指定(见正文)任意是1 
UHC统一韩语编码韩语否1-2WIN949, Windows949
UTF8Unicode,8 位所有是1-4Unicode
WIN866Windows CP866西里尔语是1ALT
WIN874Windows CP874泰语是1 
WIN1250Windows CP1250中欧是1 
WIN1251Windows CP1251西里尔语是1WIN
WIN1252Windows CP1252西欧是1 
WIN1253Windows CP1253希腊语是1 
WIN1254Windows CP1254土耳其语是1 
WIN1255Windows CP1255希伯来语是1 
WIN1256Windows CP1256阿拉伯语是1 
WIN1257Windows CP1257波罗的海是1 
WIN1258Windows CP1258越南语是1ABC, 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 字符。

22.3.2. 设置字符集

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

initdb -E EUC_JP

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

你可以在创建数据库时指定非默认编码,只要该编码与所选区域设置兼容:

createdb -E EUC_KR -T template0 --lc-collate=ko_KR.euckr --lc-ctype=ko_KR.euckr korean

这将创建一个名为korean的数据库,它使用 EUC_KR字符集和ko_KR区域设置。另一种实现方式是使用以下 SQL 命令:

CREATE DATABASE korean WITH ENCODING 'EUC_KR' LC_COLLATE='ko_KR.euckr' LC_CTYPE='ko_KR.euckr' TEMPLATE=template0;

请注意,上述命令指定复制template0数据库。如果复制任何其他数据库,就不能更改源数据库的编码和区域设置,因为这可能导致数据损坏。详见第 21.3 节。

数据库编码存储在系统目录pg_database中。可以通过 psql的-l选项或\l 命令查看它。

$ psql -l
                                         List of databases
   Name    |  Owner   | Encoding  |  Collation  |    Ctype    |          Access Privileges
-----------+----------+-----------+-------------+-------------+-------------------------------------
 clocaledb | hlinnaka | SQL_ASCII | C           | C           |
 englishdb | hlinnaka | UTF8      | en_GB.UTF8  | en_GB.UTF8  |
 japanese  | hlinnaka | UTF8      | ja_JP.UTF8  | ja_JP.UTF8  |
 korean    | hlinnaka | EUC_KR    | ko_KR.euckr | ko_KR.euckr |
 postgres  | hlinnaka | UTF8      | fi_FI.UTF8  | fi_FI.UTF8  |
 template0 | hlinnaka | UTF8      | fi_FI.UTF8  | fi_FI.UTF8  | {=c/hlinnaka,hlinnaka=CTc/hlinnaka}
 template1 | hlinnaka | UTF8      | fi_FI.UTF8  | fi_FI.UTF8  | {=c/hlinnaka,hlinnaka=CTc/hlinnaka}
(7 rows)

重要

在大多数现代操作系统上,PostgreSQL能够判断LC_CTYPE设置所隐含的字符集,并强制只允许使用与之匹配的数据库编码。在较老的系统上,你需要自行确保所用编码正是所选区域设置期望的编码。这里的错误很可能会导致区域设置相关操作(例如排序)出现奇怪的行为。

即使LC_CTYPE不是C或 POSIX,PostgreSQL 仍允许超级用户创建使用SQL_ASCII编码的数据库。正如前文所述,SQL_ASCII并不强制数据库中存储的数据具有任何特定编码,因此这种选择存在区域设置相关误行为的风险。这种设置组合已经被弃用,未来某一天可能会被完全禁止。

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

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

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

服务器字符集可用的客户端字符集
BIG5不支持作为服务器编码
EUC_CNEUC_CN, MULE_INTERNAL, UTF8
EUC_JPEUC_JP, MULE_INTERNAL, SJIS, UTF8
EUC_JIS_2004EUC_JIS_2004, SHIFT_JIS_2004, UTF8
EUC_KREUC_KR, MULE_INTERNAL, UTF8
EUC_TWEUC_TW, BIG5, MULE_INTERNAL, UTF8
GB18030不支持作为服务器编码
GBK不支持作为服务器编码
ISO_8859_5ISO_8859_5, KOI8R, MULE_INTERNAL, UTF8, WIN866, WIN1251
ISO_8859_6ISO_8859_6, UTF8
ISO_8859_7ISO_8859_7, UTF8
ISO_8859_8ISO_8859_8, UTF8
JOHAB不支持作为服务器编码
KOI8RKOI8R, ISO_8859_5, MULE_INTERNAL, UTF8, WIN866, WIN1251
KOI8UKOI8U, UTF8
LATIN1LATIN1, MULE_INTERNAL, UTF8
LATIN2LATIN2, MULE_INTERNAL, UTF8, WIN1250
LATIN3LATIN3, MULE_INTERNAL, UTF8
LATIN4LATIN4, MULE_INTERNAL, UTF8
LATIN5LATIN5, UTF8
LATIN6LATIN6, UTF8
LATIN7LATIN7, UTF8
LATIN8LATIN8, UTF8
LATIN9LATIN9, UTF8
LATIN10LATIN10, UTF8
MULE_INTERNALMULE_INTERNAL, BIG5, EUC_CN, EUC_JP, EUC_KR, EUC_TW, ISO_8859_5, KOI8R, LATIN1 至 LATIN4, SJIS, WIN866, WIN1250, WIN1251
SJIS不支持作为服务器编码
SHIFT_JIS_2004不支持作为服务器编码
SQL_ASCII任何(不会执行转换)
UHC不支持作为服务器编码
UTF8所有受支持的编码
WIN866WIN866, ISO_8859_5, KOI8R, MULE_INTERNAL, UTF8, WIN1251
WIN874WIN874, UTF8
WIN1250WIN1250, LATIN2, MULE_INTERNAL, UTF8
WIN1251WIN1251, ISO_8859_5, KOI8R, MULE_INTERNAL, UTF8, WIN866
WIN1252WIN1252, UTF8
WIN1253WIN1253, UTF8
WIN1254WIN1254, UTF8
WIN1255WIN1255, UTF8
WIN1256WIN1256, UTF8
WIN1257WIN1257, UTF8
WIN1258WIN1258, UTF8

若要启用自动字符集转换,必须告诉PostgreSQL 你希望客户端使用哪种字符集(编码)。有几种方法可以做到这一点:

  • 在psql中使用\encoding 命令。\encoding允许动态更改客户端编码。例如,要把编码改成SJIS,可以输入:

    \encoding SJIS

  • libpq(第 31.10 节)提供了控制客户端编码的函数。

  • 使用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 是不明智的。

22.3.4. 进一步阅读

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

CJKV Information Processing: Chinese, Japanese, Korean & Vietnamese Computing

其中对EUC_JP、EUC_CN、EUC_KR和EUC_TW做了详细说明。

http://www.unicode.org/

Unicode Consortium 网站。

RFC 3629

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

报告文档问题

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