23.3. 字符集支持

PostgreSQL 对字符集的支持使您可以将文本存储为多种字符集(也称为编码),包括单字节字符集(例如 ISO 8859 系列)和多字节字符集(例如 EUC(扩展 Unix 代码)), UTF-8 和 Mule 内部代码。Client 端可以透明地使用所有支持的字符集,但是不支持在服务器内部使用其中的一些字符集(即,作为服务器端编码)。使用initdb初始化 PostgreSQL 数据库集群时,将选择默认字符集。创建数据库时可以覆盖它,因此可以有多个数据库,每个数据库都有不同的字符集。

但是,一个重要的限制是每个数据库的字符集必须与数据库的LC_CTYPE(字符分类)和LC_COLLATE(字符串排序 Sequences)区域设置兼容。对于CPOSIX语言环境,允许使用任何字符集,但是对于其他 libc 提供的语言环境,只有一个字符集可以正常工作。 (但是,在 Windows 上,UTF-8 编码可以与任何语言环境一起使用.)如果配置了 ICU 支持,则 ICU 提供的语言环境可以与大多数(但不是全部)服务器端编码一起使用。

23 .3.1. 支持的字符集

Table 23.1显示了可在 PostgreSQL 中使用的字符集。

表 23.1 PostgreSQL 字符集

Name Description Language Server? ICU? Bytes/Char Aliases
BIG5 Big Five Traditional Chinese No No 1-2 WIN950 , Windows950
EUC_CN 扩展 UNIX Code-CN Simplified Chinese Yes Yes 1-3
EUC_JP 扩展 UNIX Code-JP Japanese Yes Yes 1-3
EUC_JIS_2004 扩展 UNIX Code-JP,JIS X 0213 Japanese Yes No 1-3
EUC_KR 扩展的 UNIX Code-KR Korean Yes Yes 1-3
EUC_TW 扩展 UNIX 代码 TW 繁体中文,台湾语 Yes Yes 1-3
GB18030 National Standard Chinese No No 1-4
GBK 扩展国家标准 Simplified Chinese No No 1-2 WIN936 , Windows936
ISO_8859_5 ISO 8859-5,ECMA 113 Latin/Cyrillic Yes Yes 1
ISO_8859_6 ISO 8859-6,ECMA 114 Latin/Arabic Yes Yes 1
ISO_8859_7 ISO 8859-7,ECMA 118 Latin/Greek Yes Yes 1
ISO_8859_8 ISO 8859-8,ECMA 121 Latin/Hebrew Yes Yes 1
JOHAB JOHAB Korean (Hangul) No No 1-3
KOI8R KOI8-R Cyrillic (Russian) Yes Yes 1 KOI8
KOI8U KOI8-U Cyrillic (Ukrainian) Yes Yes 1
LATIN1 ISO 8859-1,ECMA 94 Western European Yes Yes 1 ISO88591
LATIN2 ISO 8859-2,ECMA 94 Central European Yes Yes 1 ISO88592
LATIN3 ISO 8859-3,ECMA 94 South European Yes Yes 1 ISO88593
LATIN4 ISO 8859-4,ECMA 94 North European Yes Yes 1 ISO88594
LATIN5 ISO 8859-9,ECMA 128 Turkish Yes Yes 1 ISO88599
LATIN6 ISO 8859-10,ECMA 144 Nordic Yes Yes 1 ISO885910
LATIN7 ISO 8859-13 Baltic Yes Yes 1 ISO885913
LATIN8 ISO 8859-14 Celtic Yes Yes 1 ISO885914
LATIN9 ISO 8859-15 带有欧元和口音的 LATIN1 Yes Yes 1 ISO885915
LATIN10 ISO 8859-16,ASRO SR 14111 Romanian Yes No 1 ISO885916
MULE_INTERNAL ule 子内部代码 Multilingual Emacs Yes No 1-4
SJIS Shift JIS Japanese No No 1-2 Mskanji , ShiftJIS , WIN932 , Windows932
SHIFT_JIS_2004 Shift JIS,JIS X 0213 Japanese No No 1-2
SQL_ASCII 未指定(见 Literals) any Yes No 1
UHC 统一韩文代码 Korean No No 1-2 WIN949 , Windows949
UTF8 Unicode, 8-bit all Yes Yes 1-4 Unicode
WIN866 Windows CP866 Cyrillic Yes Yes 1 ALT
WIN874 Windows CP874 Thai Yes No 1
WIN1250 Windows CP1250 Central European Yes Yes 1
WIN1251 Windows CP1251 Cyrillic Yes Yes 1 WIN
WIN1252 Windows CP1252 Western European Yes Yes 1
WIN1253 Windows CP1253 Greek Yes Yes 1
WIN1254 Windows CP1254 Turkish Yes Yes 1
WIN1255 Windows CP1255 Hebrew Yes Yes 1
WIN1256 Windows CP1256 Arabic Yes Yes 1
WIN1257 Windows CP1257 Baltic Yes Yes 1
WIN1258 Windows CP1258 Vietnamese Yes Yes 1 ABC , TCVN , TCVN5712 , VSCII

并非所有的 Client 端 API 都支持所有列出的字符集。例如,PostgreSQL JDBC 驱动程序不支持MULE_INTERNALLATIN6LATIN8LATIN10

SQL_ASCII设置的行为与其他设置大不相同。当服务器字符集为SQL_ASCII时,服务器将根据 ASCII 标准解释字节值 0-127,而将字节值 128-255 视为未解释字符。设置为SQL_ASCII时将不进行编码转换。因此,此设置不是声明正在使用特定的编码,而是声明对编码的无知。在大多数情况下,如果要处理任何非 ASCII 数据,则使用SQL_ASCII设置是不明智的,因为 PostgreSQL 无法通过转换或验证非 ASCII 字符来帮助您。

23 .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数据库。复制任何其他数据库时,无法更改源数据库的编码和语言环境设置,因为这可能会导致数据损坏。有关更多信息,请参见Section 22.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)

Important

在大多数现代 os 上,PostgreSQL 可以确定LC_CTYPE设置所隐含的字符集,并且它将强制要求仅使用匹配的数据库编码。在较旧的系统上,您有责任确保使用所选语言环境所期望的编码。该区域中的错误很可能导致诸如排序之类的与语言环境相关的操作的奇怪行为。

PostgreSQL 允许超级用户使用SQL_ASCII编码创建数据库,即使LC_CTYPE不是CPOSIX也不行。如上所述,SQL_ASCII并不强制数据库中存储的数据具有任何特定的编码,因此此选择带来了与语言环境相关的行为异常的风险。不建议使用这种设置组合,有一天可能会完全禁止使用。

23 .3.3. 服务器和 Client 端之间的自动字符集转换

PostgreSQL 支持服务器和 Client 端之间针对某些字符集组合的自动字符集转换。转换信息存储在pg_conversion系统目录中。 PostgreSQL 带有一些 sched 义的转换,如Table 23.2所示。您可以使用 SQL 命令CREATE CONVERSION创建新的转换。

表 23.2Client 端/服务器字符集转换

服务器字符集 可用的 Client 端字符集
BIG5 不支持作为服务器编码
EUC_CN * EUC_CN *,MULE_INTERNALUTF8
EUC_JP * EUC_JP *,MULE_INTERNALSJISUTF8
EUC_JIS_2004 * EUC_JIS_2004 *,SHIFT_JIS_2004UTF8
EUC_KR * EUC_KR *,MULE_INTERNALUTF8
EUC_TW * EUC_TW *,BIG5MULE_INTERNALUTF8
GB18030 不支持作为服务器编码
GBK 不支持作为服务器编码
ISO_8859_5 * ISO_8859_5 *,KOI8RMULE_INTERNALUTF8WIN866WIN1251
ISO_8859_6 * ISO_8859_6 *,UTF8
ISO_8859_7 * ISO_8859_7 *,UTF8
ISO_8859_8 * ISO_8859_8 *,UTF8
JOHAB 不支持作为服务器编码
KOI8R * KOI8R *,ISO_8859_5MULE_INTERNALUTF8WIN866WIN1251
KOI8U * KOI8U *,UTF8
LATIN1 * LATIN1 *,MULE_INTERNALUTF8
LATIN2 * LATIN2 *,MULE_INTERNALUTF8WIN1250
LATIN3 * LATIN3 *,MULE_INTERNALUTF8
LATIN4 * LATIN4 *,MULE_INTERNALUTF8
LATIN5 * LATIN5 *,UTF8
LATIN6 * LATIN6 *,UTF8
LATIN7 * LATIN7 *,UTF8
LATIN8 * LATIN8 *,UTF8
LATIN9 * LATIN9 *,UTF8
LATIN10 * LATIN10 *,UTF8
MULE_INTERNAL * MULE_INTERNAL *,BIG5EUC_CNEUC_JPEUC_KREUC_TWISO_8859_5KOI8RLATIN1LATIN4SJISWIN866WIN1250WIN1251
SJIS 不支持作为服务器编码
SHIFT_JIS_2004 不支持作为服务器编码
SQL_ASCII 任何(不执行任何转换)
UHC 不支持作为服务器编码
UTF8 所有支持的编码
WIN866 * WIN866 *,ISO_8859_5KOI8RMULE_INTERNALUTF8WIN1251
WIN874 * WIN874 *,UTF8
WIN1250 * WIN1250 *,LATIN2MULE_INTERNALUTF8
WIN1251 * WIN1251 *,ISO_8859_5KOI8RMULE_INTERNALUTF8WIN866
WIN1252 * WIN1252 *,UTF8
WIN1253 * WIN1253 *,UTF8
WIN1254 * WIN1254 *,UTF8
WIN1255 * WIN1255 *,UTF8
WIN1256 * WIN1256 *,UTF8
WIN1257 * WIN1257 *,UTF8
WIN1258 * WIN1258 *,UTF8

要启用自动字符集转换,您必须告诉 PostgreSQL 您想在 Client 端中使用的字符集(编码)。有几种方法可以实现此目的:

\encoding SJIS
SET CLIENT_ENCODING TO 'value';

您也可以为此使用标准 SQL 语法SET NAMES

SET NAMES 'value';

要查询当前的 Client 端编码:

SHOW client_encoding;

要返回默认编码:

RESET client_encoding;

如果无法转换特定字符(假设您为服务器选择了EUC_JP,为 Client 端选择了LATIN1,并且返回了一些日语字符,但这些字符在LATIN1中没有表示),则会报告错误。

如果 Client 端字符集定义为SQL_ASCII,则无论服务器的字符集如何,都将禁用编码转换。和服务器一样,除非使用全 ASCII 数据,否则使用SQL_ASCII是不明智的。

23 .3.4. 进一步阅读

这些都是开始学习各种编码系统的好资源。

上一章 首页 下一章