Skip to content

24.3. 字符集支持#

24.3.1. 支持的字符集
24.3.2. 设置字符集
24.3.3. 服务器和客户端之间的自动字符集转换
24.3.4. 可用的字符集转换
24.3.5. 延伸阅读

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

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

24.3.1. 受支持的字符集#

表 24.3显示了可在PostgreSQL中使用的字符集。

表 24.3.PostgreSQL字符集

名称说明语言服务器?ICU?字节/字符别名
BIG5大五码繁体中文1–2WIN950Windows950
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–2WIN936Windows936
ISO_8859_5ISO 8859-5, 113拉丁语/西里尔语1
ISO_8859_6ISO 8859-6、 114拉丁语/阿拉伯语1
ISO_8859_7ISO 8859-7、 118拉丁语/希腊语1
ISO_8859_8ISO 8859-8、 121拉丁语/希伯来语1
JOHAB韩语(韩文)1–3
KOI8R8-R西里尔语(俄语)1KOI8
KOI8U8-U西里尔语(乌克兰语)1
LATIN1ISO 8859-1、 94西欧语1ISO88591
LATIN2ISO 8859-2、 94中欧语1ISO88592
LATIN3ISO 8859-3、 94南欧语1ISO88593
LATIN4ISO 8859-4、 94北欧语1ISO88594
LATIN5ISO 8859-9、 128土耳其语1ISO88599
LATIN6ISO 8859-10、 144北欧语1ISO885910
LATIN7ISO 8859-13波罗的海语1ISO885913
LATIN8ISO 8859-14凯尔特语1ISO885914
LATIN9ISO 8859-15带有欧元和重音符号的 LATIN11ISO885915
LATIN10ISO 8859-16、 SR 14111罗马尼亚语1ISO885916
MULE_INTERNALMule 内部代码多语言 Emacs1–4
SJISShift JIS日语1–2MskanjiShiftJISWIN932Windows932
SHIFT_JIS_2004Shift JIS、JIS X 0213日语1–2
SQL_ASCII未指定(见文本)任意1
UHC统一韩文代码韩语1–2WIN949Windows949
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越南语1ABCTCVNTCVN5712VSCII

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

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不是CPOSIX。如上所述,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_CNEUC_CNMULE_INTERNALUTF8
EUC_JPEUC_JPMULE_INTERNALSJISUTF8
EUC_JIS_2004EUC_JIS_2004SHIFT_JIS_2004UTF8
EUC_KREUC_KRMULE_INTERNALUTF8
EUC_TWEUC_TWBIG5MULE_INTERNALUTF8
GB18030不支持作为服务器编码
GBK不支持作为服务器编码
ISO_8859_5ISO_8859_5KOI8RMULE_INTERNALUTF8WIN866WIN1251
ISO_8859_6ISO_8859_6UTF8
ISO_8859_7ISO_8859_7UTF8
ISO_8859_8ISO_8859_8UTF8
JOHAB不支持作为服务器编码
KOI8RKOI8RISO_8859_5MULE_INTERNALUTF8WIN866WIN1251
KOI8UKOI8UUTF8
LATIN1LATIN1MULE_INTERNALUTF8
LATIN2LATIN2MULE_INTERNALUTF8WIN1250
LATIN3LATIN3MULE_INTERNALUTF8
LATIN4LATIN4MULE_INTERNALUTF8
LATIN5LATIN5UTF8
LATIN6LATIN6UTF8
LATIN7LATIN7UTF8
LATIN8LATIN8UTF8
LATIN9LATIN9UTF8
LATIN10LATIN10UTF8
MULE_INTERNALMULE_INTERNALBIG5EUC_CNEUC_JPEUC_KREUC_TWISO_8859_5KOI8RLATIN1LATIN4SJISWIN866WIN1250WIN1251
SJIS不支持作为服务器编码
SHIFT_JIS_2004不支持作为服务器编码
SQL_ASCII任何(不执行转换)
UHC不支持作为服务器编码
UTF8所有支持的编码
WIN866WIN866ISO_8859_5KOI8RMULE_INTERNALUTF8WIN1251
WIN874WIN874UTF8
WIN1250WIN1250LATIN2MULE_INTERNALUTF8
WIN1251WIN1251, ISO_8859_5, KOI8R, MULE_INTERNAL, UTF8, WIN866
WIN1252WIN1252, UTF8
WIN1253WIN1253, UTF8
WIN1254WIN1254, UTF8
WIN1255WIN1255, UTF8
WIN1256WIN1256, UTF8
WIN1257WIN1257, UTF8
WIN1258WIN1258, UTF8

表格 24.5. 所有内置字符集转换

转换名称 [a]源编码目标编码
big5_to_euc_twBIG5EUC_TW
big5_to_micBIG5MULE_INTERNAL
big5_to_utf8BIG5UTF8
euc_cn_to_micEUC_CNMULE_INTERNAL
euc_cn_to_utf8EUC_CNUTF8
euc_jp_to_micEUC_JPMULE_INTERNAL
euc_jp_to_sjisEUC_JPSJIS
euc_jp_to_utf8EUC_JPUTF8
euc_kr_to_micEUC_KRMULE_INTERNAL
euc_kr_to_utf8EUC_KRUTF8
euc_tw_to_big5EUC_TWBIG5
euc_tw_to_micEUC_TWMULE_INTERNAL
euc_tw_to_utf8EUC_TWUTF8
gb18030_to_utf8GB18030UTF8
gbk_to_utf8GBKUTF8
iso_8859_10_to_utf8LATIN6UTF8
iso_8859_13_to_utf8LATIN7UTF8
iso_8859_14_to_utf8LATIN8UTF8
iso_8859_15_to_utf8LATIN9UTF8
iso_8859_16_to_utf8LATIN10UTF8
iso_8859_1_to_micLATIN1MULE_INTERNAL
iso_8859_1_to_utf8LATIN1UTF8
iso_8859_2_to_micLATIN2MULE_INTERNAL
iso_8859_2_to_utf8LATIN2UTF8
iso_8859_2_to_windows_1250LATIN2WIN1250
iso_8859_3_to_micLATIN3MULE_INTERNAL
iso_8859_3_to_utf8LATIN3UTF8
iso_8859_4_to_micLATIN4MULE_INTERNAL
iso_8859_4_to_utf8LATIN4UTF8
iso_8859_5_to_koi8_rISO_8859_5KOI8R
iso_8859_5_to_micISO_8859_5MULE_INTERNAL
iso_8859_5_to_utf8ISO_8859_5UTF8
iso_8859_5_to_windows_1251ISO_8859_5WIN1251
iso_8859_5_to_windows_866ISO_8859_5WIN866
iso_8859_6_to_utf8ISO_8859_6UTF8
iso_8859_7_to_utf8ISO_8859_7UTF8
iso_8859_8_to_utf8ISO_8859_8UTF8
iso_8859_9_to_utf8LATIN5UTF8
johab_to_utf8JOHABUTF8
koi8_r_to_iso_8859_5KOI8RISO_8859_5
koi8_r_to_micKOI8RMULE_INTERNAL
koi8_r_to_utf8KOI8RUTF8
koi8_r_to_windows_1251KOI8RWIN1251
koi8_r_to_windows_866KOI8RWIN866
koi8_u_to_utf8KOI8UUTF8
mic_to_big5MULE_INTERNALBIG5
mic_to_euc_cnMULE_INTERNALEUC_CN
mic_to_euc_jpMULE_INTERNALEUC_JP
mic_to_euc_krMULE_INTERNALEUC_KR
mic_to_euc_twMULE_INTERNALEUC_TW
mic_to_iso_8859_1MULE_INTERNALLATIN1
mic_to_iso_8859_2MULE_INTERNALLATIN2
mic_to_iso_8859_3MULE_INTERNALLATIN3
mic_to_iso_8859_4MULE_INTERNALLATIN4
mic_to_iso_8859_5MULE_INTERNALISO_8859_5
mic_to_koi8_rMULE_INTERNALKOI8R
mic_to_sjisMULE_INTERNALSJIS
mic_to_windows_1250MULE_INTERNALWIN1250
mic_to_windows_1251MULE_INTERNALWIN1251
mic_to_windows_866MULE_INTERNALWIN866
sjis_to_euc_jpSJISEUC_JP
sjis_to_micSJISMULE_INTERNAL
sjis_to_utf8SJISUTF8
windows_1258_to_utf8WIN1258UTF8
uhc_to_utf8UHCUTF8
utf8_to_big5UTF8BIG5
utf8_to_euc_cnUTF8EUC_CN
utf8_to_euc_jpUTF8EUC_JP
utf8_to_euc_krUTF8EUC_KR
utf8_to_euc_twUTF8EUC_TW
utf8_to_gb18030UTF8GB18030
utf8_to_gbkUTF8GBK
utf8_to_iso_8859_1UTF8LATIN1
utf8_to_iso_8859_10UTF8LATIN6
utf8_to_iso_8859_13UTF8LATIN7
utf8_to_iso_8859_14UTF8LATIN8
utf8_to_iso_8859_15UTF8LATIN9
utf8_to_iso_8859_16UTF8LATIN10
utf8_to_iso_8859_2UTF8LATIN2
utf8_to_iso_8859_3UTF8LATIN3
utf8_to_iso_8859_4UTF8LATIN4
utf8_to_iso_8859_5UTF8ISO_8859_5
utf8_to_iso_8859_6UTF8ISO_8859_6
utf8_to_iso_8859_7UTF8ISO_8859_7
utf8_to_iso_8859_8UTF8ISO_8859_8
utf8_to_iso_8859_9UTF8LATIN5
utf8_to_johabUTF8JOHAB
utf8_to_koi8_rUTF8KOI8R
utf8_to_koi8_uUTF8KOI8U
utf8_to_sjisUTF8SJIS
utf8_to_windows_1258UTF8WIN1258
utf8_to_uhcUTF8UHC
utf8_to_windows_1250UTF8WIN1250
utf8_to_windows_1251UTF8WIN1251
utf8_to_windows_1252UTF8WIN1252
utf8_to_windows_1253UTF8WIN1253
utf8_to_windows_1254UTF8WIN1254
utf8_to_windows_1255UTF8WIN1255
utf8_to_windows_1256UTF8WIN1256
utf8_to_windows_1257UTF8WIN1257
utf8_to_windows_866UTF8WIN866
utf8_to_windows_874UTF8WIN874
windows_1250_to_iso_8859_2WIN1250LATIN2
windows_1250_to_micWIN1250MULE_INTERNAL
windows_1250_to_utf8WIN1250UTF8
windows_1251_to_iso_8859_5WIN1251ISO_8859_5
windows_1251_to_koi8_rWIN1251KOI8R
windows_1251_to_micWIN1251MULE_INTERNAL
windows_1251_to_utf8WIN1251UTF8
windows_1251_to_windows_866WIN1251WIN866
windows_1252_to_utf8WIN1252UTF8
windows_1256_to_utf8WIN1256UTF8
windows_866_to_iso_8859_5WIN866ISO_8859_5
windows_866_to_koi8_rWIN866KOI8R
windows_866_to_micWIN866MULE_INTERNAL
windows_866_to_utf8WIN866UTF8
windows_866_to_windows_1251WIN866WIN
windows_874_to_utf8WIN874UTF8
euc_jis_2004_to_utf8EUC_JIS_2004UTF8
utf8_to_euc_jis_2004UTF8EUC_JIS_2004
shift_jis_2004_to_utf8SHIFT_JIS_2004UTF8
utf8_to_shift_jis_2004UTF8SHIFT_JIS_2004
euc_jis_2004_to_shift_jis_2004EUC_JIS_2004SHIFT_JIS_2004
shift_jis_2004_to_euc_jis_2004SHIFT_JIS_2004EUC_JIS_2004

[a] 转换名称遵循标准命名方案:源编码的官方名称,其中所有非字母数字字符替换为下划线,后跟 _to_,后跟类似处理的目标编码名称。因此,这些名称有时偏离 表 24.3 中显示的惯用编码名称。

24.3.5. 进一步阅读#

以下是一些了解各种编码系统的好资源。

CJKV 信息处理:中文、日语、韩语和越南语计算

包含 EUC_JPEUC_CNEUC_KREUC_TW 的详细说明。

https://www.unicode.org/

Unicode 联盟网站。

RFC 3629

-8(8 位 UCS/Unicode 转换格式)在此定义。