24.3. 字符集支持#
PostgreSQL中的字符集支持允许您在各种字符集中存储文本(也称为编码),包括单字节字符集,如 ISO 8859 系列,以及多字节字符集,如EUC(扩展 Unix 代码)、UTF-8 和 Mule 内部代码。所有受支持的字符集都可以由客户端透明地使用,但少数字符集不受服务器内使用(即作为服务器端编码)的支持。在使用initdb
初始化PostgreSQL数据库集群时,将选择默认字符集。在创建数据库时可以覆盖它,因此您可以拥有多个具有不同字符集的数据库。
然而,一个重要的限制是,每个数据库的字符集必须与其数据库的LC_CTYPE
(字符分类)和LC_COLLATE
(字符串排序顺序)区域设置兼容。对于C
或POSIX
区域设置,允许使用任何字符集,但对于其他 libc 提供的区域设置,只有一组字符集可以正常工作。(然而,在 Windows 上,UTF-8 编码可以与任何区域设置一起使用。)如果您配置了 ICU 支持,则 ICU 提供的区域设置可以与大多数但并非所有服务器端编码一起使用。
24.3.1. 受支持的字符集#
表 24.3显示了可在PostgreSQL中使用的字符集。
表 24.3.PostgreSQL字符集
名称 | 说明 | 语言 | 服务器? | ICU? | 字节/字符 | 别名 |
---|---|---|---|---|---|---|
BIG5 | 大五码 | 繁体中文 | 否 | 否 | 1–2 | WIN950 、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–2 | WIN936 、Windows936 |
ISO_8859_5 | ISO 8859-5, 113 | 拉丁语/西里尔语 | 是 | 是 | 1 | |
ISO_8859_6 | ISO 8859-6、 114 | 拉丁语/阿拉伯语 | 是 | 是 | 1 | |
ISO_8859_7 | ISO 8859-7、 118 | 拉丁语/希腊语 | 是 | 是 | 1 | |
ISO_8859_8 | ISO 8859-8、 121 | 拉丁语/希伯来语 | 是 | 是 | 1 | |
JOHAB | 韩语(韩文) | 否 | 否 | 1–3 | ||
KOI8R | 8-R | 西里尔语(俄语) | 是 | 是 | 1 | KOI8 |
KOI8U | 8-U | 西里尔语(乌克兰语) | 是 | 是 | 1 | |
LATIN1 | ISO 8859-1、 94 | 西欧语 | 是 | 是 | 1 | ISO88591 |
LATIN2 | ISO 8859-2、 94 | 中欧语 | 是 | 是 | 1 | ISO88592 |
LATIN3 | ISO 8859-3、 94 | 南欧语 | 是 | 是 | 1 | ISO88593 |
LATIN4 | ISO 8859-4、 94 | 北欧语 | 是 | 是 | 1 | ISO88594 |
LATIN5 | ISO 8859-9、 128 | 土耳其语 | 是 | 是 | 1 | ISO88599 |
LATIN6 | ISO 8859-10、 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、 SR 14111 | 罗马尼亚语 | 是 | 否 | 1 | ISO885916 |
MULE_INTERNAL | Mule 内部代码 | 多语言 Emacs | 是 | 否 | 1–4 | |
SJIS | Shift JIS | 日语 | 否 | 否 | 1–2 | Mskanji 、ShiftJIS 、WIN932 、Windows932 |
SHIFT_JIS_2004 | Shift JIS、JIS X 0213 | 日语 | 否 | 否 | 1–2 | |
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都支持所有列出的字符集。例如,PostgreSQLJDBC 驱动程序不支持MULE_INTERNAL
、LATIN6
、LATIN8
和LATIN10
。
SQL_ASCII
设置的行为与其他设置有很大不同。当服务器字符集为SQL_ASCII
时,服务器将根据 ASCII 标准解释字节值 0-127,而将字节值 128-255 视为未解释的字符。当设置是SQL_ASCII
时,不会执行任何编码转换。因此,此设置并不是声明正在使用特定编码,而是声明对编码一无所知。在大多数情况下,如果您正在使用任何非 ASCII 数据,则不建议使用SQL_ASCII
设置,因为PostgreSQL无法通过转换或验证非 ASCII 字符来帮助您。
24.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
数据库。在复制任何其他数据库时,编码和语言环境设置无法从源数据库的设置中更改,因为这可能会导致数据损坏。有关更多信息,请参见第 23.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
设置隐含哪个字符集,并且它将强制仅使用匹配的数据库编码。在较旧的系统上,您有责任确保使用您选择的区域设置所期望的编码。此区域中出现错误可能会导致依赖区域设置的操作(例如排序)出现奇怪的行为。
PostgreSQL将允许超级用户创建具有SQL_ASCII
编码的数据库,即使LC_CTYPE
不是C
或POSIX
。如上所述,SQL_ASCII
不会强制要求存储在数据库中的数据具有任何特定编码,因此此选择会带来依赖区域设置的错误行为风险。不推荐使用此组合设置,并且将来可能会完全禁止使用。
24.3.3. 服务器和客户端之间的自动字符集转换#
PostgreSQL支持服务器和客户端之间针对许多字符集组合的自动字符集转换(第 24.3.4 节显示了哪些组合)。
要启用自动字符集转换,您必须告诉PostgreSQL您想在客户端中使用的字符集(编码)。有几种方法可以实现此目的
在 psql 中使用
\encoding
命令。\encoding
允许您即时更改客户端编码。例如,要将编码更改为SJIS
,请键入\encoding SJIS
libpq(第 34.11 节)具有控制客户端编码的函数。
使用
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
,则禁用编码转换,而不管服务器的字符集是什么。(但是,如果服务器的字符集不是SQL_ASCII
,服务器仍会检查传入数据是否对该编码有效;因此,最终效果就好像客户端字符集与服务器字符集相同。)对于服务器来说,除非您使用全 ASCII 数据,否则不建议使用SQL_ASCII
。
24.3.4. 可用的字符集转换#
PostgreSQL允许在pg_conversion
系统目录中列出了转换函数的任何两个字符集之间进行转换。PostgreSQL附带一些预定义转换,如表 24.4中总结的,并在表 24.5中更详细地显示的。您可以使用 SQL 命令CREATE CONVERSION创建新转换。(要用于自动客户端/服务器转换,必须为转换的字符集对标记为“default”。)
表 24.4. 内置客户端/服务器字符集转换
服务器字符集 | 可用的客户端字符集 |
---|---|
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 |
表格 24.5. 所有内置字符集转换
转换名称 [a] | 源编码 | 目标编码 |
---|---|---|
big5_to_euc_tw | BIG5 | EUC_TW |
big5_to_mic | BIG5 | MULE_INTERNAL |
big5_to_utf8 | BIG5 | UTF8 |
euc_cn_to_mic | EUC_CN | MULE_INTERNAL |
euc_cn_to_utf8 | EUC_CN | UTF8 |
euc_jp_to_mic | EUC_JP | MULE_INTERNAL |
euc_jp_to_sjis | EUC_JP | SJIS |
euc_jp_to_utf8 | EUC_JP | UTF8 |
euc_kr_to_mic | EUC_KR | MULE_INTERNAL |
euc_kr_to_utf8 | EUC_KR | UTF8 |
euc_tw_to_big5 | EUC_TW | BIG5 |
euc_tw_to_mic | EUC_TW | MULE_INTERNAL |
euc_tw_to_utf8 | EUC_TW | UTF8 |
gb18030_to_utf8 | GB18030 | UTF8 |
gbk_to_utf8 | GBK | UTF8 |
iso_8859_10_to_utf8 | LATIN6 | UTF8 |
iso_8859_13_to_utf8 | LATIN7 | UTF8 |
iso_8859_14_to_utf8 | LATIN8 | UTF8 |
iso_8859_15_to_utf8 | LATIN9 | UTF8 |
iso_8859_16_to_utf8 | LATIN10 | UTF8 |
iso_8859_1_to_mic | LATIN1 | MULE_INTERNAL |
iso_8859_1_to_utf8 | LATIN1 | UTF8 |
iso_8859_2_to_mic | LATIN2 | MULE_INTERNAL |
iso_8859_2_to_utf8 | LATIN2 | UTF8 |
iso_8859_2_to_windows_1250 | LATIN2 | WIN1250 |
iso_8859_3_to_mic | LATIN3 | MULE_INTERNAL |
iso_8859_3_to_utf8 | LATIN3 | UTF8 |
iso_8859_4_to_mic | LATIN4 | MULE_INTERNAL |
iso_8859_4_to_utf8 | LATIN4 | UTF8 |
iso_8859_5_to_koi8_r | ISO_8859_5 | KOI8R |
iso_8859_5_to_mic | ISO_8859_5 | MULE_INTERNAL |
iso_8859_5_to_utf8 | ISO_8859_5 | UTF8 |
iso_8859_5_to_windows_1251 | ISO_8859_5 | WIN1251 |
iso_8859_5_to_windows_866 | ISO_8859_5 | WIN866 |
iso_8859_6_to_utf8 | ISO_8859_6 | UTF8 |
iso_8859_7_to_utf8 | ISO_8859_7 | UTF8 |
iso_8859_8_to_utf8 | ISO_8859_8 | UTF8 |
iso_8859_9_to_utf8 | LATIN5 | UTF8 |
johab_to_utf8 | JOHAB | UTF8 |
koi8_r_to_iso_8859_5 | KOI8R | ISO_8859_5 |
koi8_r_to_mic | KOI8R | MULE_INTERNAL |
koi8_r_to_utf8 | KOI8R | UTF8 |
koi8_r_to_windows_1251 | KOI8R | WIN1251 |
koi8_r_to_windows_866 | KOI8R | WIN866 |
koi8_u_to_utf8 | KOI8U | UTF8 |
mic_to_big5 | MULE_INTERNAL | BIG5 |
mic_to_euc_cn | MULE_INTERNAL | EUC_CN |
mic_to_euc_jp | MULE_INTERNAL | EUC_JP |
mic_to_euc_kr | MULE_INTERNAL | EUC_KR |
mic_to_euc_tw | MULE_INTERNAL | EUC_TW |
mic_to_iso_8859_1 | MULE_INTERNAL | LATIN1 |
mic_to_iso_8859_2 | MULE_INTERNAL | LATIN2 |
mic_to_iso_8859_3 | MULE_INTERNAL | LATIN3 |
mic_to_iso_8859_4 | MULE_INTERNAL | LATIN4 |
mic_to_iso_8859_5 | MULE_INTERNAL | ISO_8859_5 |
mic_to_koi8_r | MULE_INTERNAL | KOI8R |
mic_to_sjis | MULE_INTERNAL | SJIS |
mic_to_windows_1250 | MULE_INTERNAL | WIN1250 |
mic_to_windows_1251 | MULE_INTERNAL | WIN1251 |
mic_to_windows_866 | MULE_INTERNAL | WIN866 |
sjis_to_euc_jp | SJIS | EUC_JP |
sjis_to_mic | SJIS | MULE_INTERNAL |
sjis_to_utf8 | SJIS | UTF8 |
windows_1258_to_utf8 | WIN1258 | UTF8 |
uhc_to_utf8 | UHC | UTF8 |
utf8_to_big5 | UTF8 | BIG5 |
utf8_to_euc_cn | UTF8 | EUC_CN |
utf8_to_euc_jp | UTF8 | EUC_JP |
utf8_to_euc_kr | UTF8 | EUC_KR |
utf8_to_euc_tw | UTF8 | EUC_TW |
utf8_to_gb18030 | UTF8 | GB18030 |
utf8_to_gbk | UTF8 | GBK |
utf8_to_iso_8859_1 | UTF8 | LATIN1 |
utf8_to_iso_8859_10 | UTF8 | LATIN6 |
utf8_to_iso_8859_13 | UTF8 | LATIN7 |
utf8_to_iso_8859_14 | UTF8 | LATIN8 |
utf8_to_iso_8859_15 | UTF8 | LATIN9 |
utf8_to_iso_8859_16 | UTF8 | LATIN10 |
utf8_to_iso_8859_2 | UTF8 | LATIN2 |
utf8_to_iso_8859_3 | UTF8 | LATIN3 |
utf8_to_iso_8859_4 | UTF8 | LATIN4 |
utf8_to_iso_8859_5 | UTF8 | ISO_8859_5 |
utf8_to_iso_8859_6 | UTF8 | ISO_8859_6 |
utf8_to_iso_8859_7 | UTF8 | ISO_8859_7 |
utf8_to_iso_8859_8 | UTF8 | ISO_8859_8 |
utf8_to_iso_8859_9 | UTF8 | LATIN5 |
utf8_to_johab | UTF8 | JOHAB |
utf8_to_koi8_r | UTF8 | KOI8R |
utf8_to_koi8_u | UTF8 | KOI8U |
utf8_to_sjis | UTF8 | SJIS |
utf8_to_windows_1258 | UTF8 | WIN1258 |
utf8_to_uhc | UTF8 | UHC |
utf8_to_windows_1250 | UTF8 | WIN1250 |
utf8_to_windows_1251 | UTF8 | WIN1251 |
utf8_to_windows_1252 | UTF8 | WIN1252 |
utf8_to_windows_1253 | UTF8 | WIN1253 |
utf8_to_windows_1254 | UTF8 | WIN1254 |
utf8_to_windows_1255 | UTF8 | WIN1255 |
utf8_to_windows_1256 | UTF8 | WIN1256 |
utf8_to_windows_1257 | UTF8 | WIN1257 |
utf8_to_windows_866 | UTF8 | WIN866 |
utf8_to_windows_874 | UTF8 | WIN874 |
windows_1250_to_iso_8859_2 | WIN1250 | LATIN2 |
windows_1250_to_mic | WIN1250 | MULE_INTERNAL |
windows_1250_to_utf8 | WIN1250 | UTF8 |
windows_1251_to_iso_8859_5 | WIN1251 | ISO_8859_5 |
windows_1251_to_koi8_r | WIN1251 | KOI8R |
windows_1251_to_mic | WIN1251 | MULE_INTERNAL |
windows_1251_to_utf8 | WIN1251 | UTF8 |
windows_1251_to_windows_866 | WIN1251 | WIN866 |
windows_1252_to_utf8 | WIN1252 | UTF8 |
windows_1256_to_utf8 | WIN1256 | UTF8 |
windows_866_to_iso_8859_5 | WIN866 | ISO_8859_5 |
windows_866_to_koi8_r | WIN866 | KOI8R |
windows_866_to_mic | WIN866 | MULE_INTERNAL |
windows_866_to_utf8 | WIN866 | UTF8 |
windows_866_to_windows_1251 | WIN866 | WIN |
windows_874_to_utf8 | WIN874 | UTF8 |
euc_jis_2004_to_utf8 | EUC_JIS_2004 | UTF8 |
utf8_to_euc_jis_2004 | UTF8 | EUC_JIS_2004 |
shift_jis_2004_to_utf8 | SHIFT_JIS_2004 | UTF8 |
utf8_to_shift_jis_2004 | UTF8 | SHIFT_JIS_2004 |
euc_jis_2004_to_shift_jis_2004 | EUC_JIS_2004 | SHIFT_JIS_2004 |
shift_jis_2004_to_euc_jis_2004 | SHIFT_JIS_2004 | EUC_JIS_2004 |
24.3.5. 进一步阅读#
以下是一些了解各种编码系统的好资源。
- CJKV 信息处理:中文、日语、韩语和越南语计算
包含
EUC_JP
、EUC_CN
、EUC_KR
、EUC_TW
的详细说明。- https://www.unicode.org/
Unicode 联盟网站。
- RFC 3629
-8(8 位 UCS/Unicode 转换格式)在此定义。