On this page
23.3. 字符集支持
PostgreSQL 对字符集的支持使您可以将文本存储为多种字符集(也称为编码),包括单字节字符集(例如 ISO 8859 系列)和多字节字符集(例如 EUC(扩展 Unix 代码)), UTF-8 和 Mule 内部代码。Client 端可以透明地使用所有支持的字符集,但是不支持在服务器内部使用其中的一些字符集(即,作为服务器端编码)。使用initdb
初始化 PostgreSQL 数据库集群时,将选择默认字符集。创建数据库时可以覆盖它,因此可以有多个数据库,每个数据库都有不同的字符集。
但是,一个重要的限制是每个数据库的字符集必须与数据库的LC_CTYPE
(字符分类)和LC_COLLATE
(字符串排序 Sequences)区域设置兼容。对于C
或POSIX
语言环境,允许使用任何字符集,但是对于其他 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_INTERNAL
,LATIN6
,LATIN8
和LATIN10
。
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
不是C
或POSIX
也不行。如上所述,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_INTERNAL ,UTF8 |
EUC_JP |
* EUC_JP *,MULE_INTERNAL ,SJIS ,UTF8 |
EUC_JIS_2004 |
* EUC_JIS_2004 *,SHIFT_JIS_2004 ,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 |
不支持作为服务器编码 |
KOI8R |
* KOI8R *,ISO_8859_5 ,MULE_INTERNAL ,UTF8 ,WIN866 ,WIN1251 |
KOI8U |
* KOI8U *,UTF8 |
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 至LATIN4 ,SJIS ,WIN866 ,WIN1250 ,WIN1251 |
SJIS |
不支持作为服务器编码 |
SHIFT_JIS_2004 |
不支持作为服务器编码 |
SQL_ASCII |
任何(不执行任何转换) |
UHC |
不支持作为服务器编码 |
UTF8 |
所有支持的编码 |
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 您想在 Client 端中使用的字符集(编码)。有几种方法可以实现此目的:
- 在 psql 中使用
\encoding
命令。\encoding
允许您即时更改 Client 端编码。例如,要将编码更改为SJIS
,请 Importing:
\encoding SJIS
libpq(Section 33.10)具有控制 Client 端编码的功能。
使用
SET client_encoding TO
。可以使用以下 SQL 命令来设置 Client 端编码:
SET CLIENT_ENCODING TO 'value';
您也可以为此使用标准 SQL 语法SET NAMES
:
SET NAMES 'value';
要查询当前的 Client 端编码:
SHOW client_encoding;
要返回默认编码:
RESET client_encoding;
使用
PGCLIENTENCODING
。如果在 Client 端环境中定义了环境变量PGCLIENTENCODING
,则在与服务器构建连接时会自动选择该 Client 端编码。 (随后可以使用上述任何其他方法覆盖此方法.)使用配置变量client_encoding。如果设置了
client_encoding
变量,则在与服务器构建连接时会自动选择该 Client 端编码。 (随后可以使用上述任何其他方法覆盖此方法.)
如果无法转换特定字符(假设您为服务器选择了EUC_JP
,为 Client 端选择了LATIN1
,并且返回了一些日语字符,但这些字符在LATIN1
中没有表示),则会报告错误。
如果 Client 端字符集定义为SQL_ASCII
,则无论服务器的字符集如何,都将禁用编码转换。和服务器一样,除非使用全 ASCII 数据,否则使用SQL_ASCII
是不明智的。
23 .3.4. 进一步阅读
这些都是开始学习各种编码系统的好资源。
-
- CJKV 信息处理:中文,日文,韩文和越南文计算*
- 包含
EUC_JP
,EUC_CN
,EUC_KR
,EUC_TW
的详细说明。
-
- Unicodeunion 的网站。
RFC 3629
- 此处定义了 UTF-8(8 位 UCS/Unicode 转换格式)。