2024年9月26日: PostgreSQL 17 发布!
支持的版本:当前 (17) / 16 / 15 / 14 / 13 / 12
开发版本:devel
不支持的版本: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

23.3. 字符集支持 #

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

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

23.3.1. 支持的字符集 #

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

表 23.3. PostgreSQL 字符集

名称 描述 语言 服务器? ICU? 字节/字符 别名
BIG5 Big Five 繁体中文 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,ECMA 113 拉丁语/西里尔字母 1  
ISO_8859_6 ISO 8859-6,ECMA 114 拉丁语/阿拉伯语 1  
ISO_8859_7 ISO 8859-7,ECMA 118 拉丁语/希腊语 1  
ISO_8859_8 ISO 8859-8,ECMA 121 拉丁语/希伯来语 1  
JOHAB JOHAB 韩语(韩文) 1–3  
KOI8R KOI8-R 西里尔字母(俄语) 1 KOI8
KOI8U KOI8-U 西里尔字母(乌克兰语) 1  
LATIN1 ISO 8859-1,ECMA 94 西欧 1 ISO88591
LATIN2 ISO 8859-2,ECMA 94 中欧 1 ISO88592
LATIN3 ISO 8859-3,ECMA 94 南欧 1 ISO88593
LATIN4 ISO 8859-4,ECMA 94 北欧 1 ISO88594
LATIN5 ISO 8859-9,ECMA 128 土耳其语 1 ISO88599
LATIN6 ISO 8859-10,ECMA 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,ASROSR 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都支持所有列出的字符集。例如,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 数据库。复制任何其他数据库时,无法更改其编码和区域设置,因为这可能会导致数据损坏。有关更多信息,请参见第 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)

重要

在大多数现代操作系统上,PostgreSQL 可以确定 LC_CTYPE 设置隐含的字符集,并且它将强制仅使用匹配的数据库编码。在较旧的系统上,您有责任确保使用所选区域设置预期的编码。这方面的错误很可能导致依赖于区域设置的操作(如排序)出现异常行为。

PostgreSQL 将允许超级用户即使 LC_CTYPE 不是 CPOSIX,也可以创建具有 SQL_ASCII 编码的数据库。如上所述,SQL_ASCII 不会强制数据库中存储的数据具有任何特定编码,因此此选择存在依赖于区域设置的异常行为的风险。使用此设置组合已弃用,并且将来可能会完全禁止。

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

PostgreSQL 支持许多字符集组合之间的服务器和客户端之间的自动字符集转换(第 23.3.4 节 显示了哪些组合)。

要启用自动字符集转换,您必须告诉 PostgreSQL 您希望在客户端中使用的字符集(编码)。有几种方法可以实现这一点

  • 在 psql 中使用 \encoding 命令。\encoding 允许您动态更改客户端编码。例如,要将编码更改为 SJIS,请键入

    \encoding SJIS
    
  • libpq(第 32.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

23.3.4. 可用的字符集转换 #

PostgreSQL 允许在任何两个字符集之间进行转换,前提是 pg_conversion 系统目录中列出了转换函数。PostgreSQL 带有一些预定义的转换,如 表 23.4 中总结,并在 表 23.5 中更详细地展示。您可以使用 SQL 命令 CREATE CONVERSION 创建新的转换。(要用于自动客户端/服务器转换,转换必须在其字符集对中标记为 default。)

表 23.4. 内置客户端/服务器字符集转换

服务器字符集 可用的客户端字符集
BIG5 不支持作为服务器编码
EUC_CN EUC_CNMULE_INTERNALUTF8
EUC_JP EUC_JPMULE_INTERNALSJISUTF8
EUC_JIS_2004 EUC_JIS_2004SHIFT_JIS_2004UTF8
EUC_KR EUC_KRMULE_INTERNALUTF8
EUC_TW EUC_TWBIG5MULE_INTERNALUTF8
GB18030 不支持作为服务器编码
GBK 不支持作为服务器编码
ISO_8859_5 ISO_8859_5KOI8RMULE_INTERNALUTF8WIN866WIN1251
ISO_8859_6 ISO_8859_6UTF8
ISO_8859_7 ISO_8859_7UTF8
ISO_8859_8 ISO_8859_8UTF8
JOHAB 不支持作为服务器编码
KOI8R KOI8RISO_8859_5MULE_INTERNALUTF8WIN866WIN1251
KOI8U KOI8UUTF8
LATIN1 LATIN1MULE_INTERNALUTF8
LATIN2 LATIN2MULE_INTERNALUTF8WIN1250
LATIN3 LATIN3MULE_INTERNALUTF8
LATIN4 LATIN4MULE_INTERNALUTF8
LATIN5 LATIN5UTF8
LATIN6 LATIN6UTF8
LATIN7 LATIN7UTF8
LATIN8 LATIN8UTF8
LATIN9 LATIN9UTF8
LATIN10 LATIN10UTF8
MULE_INTERNAL MULE_INTERNALBIG5EUC_CNEUC_JPEUC_KREUC_TWISO_8859_5KOI8RLATIN1LATIN4SJISWIN866WIN1250WIN1251
SJIS 不支持作为服务器编码
SHIFT_JIS_2004 不支持作为服务器编码
SQL_ASCII 任何(不会执行转换)
UHC 不支持作为服务器编码
UTF8 所有支持的编码
WIN866 WIN866ISO_8859_5KOI8RMULE_INTERNALUTF8WIN1251
WIN874 WIN874UTF8
WIN1250 WIN1250LATIN2MULE_INTERNALUTF8
WIN1251 WIN1251ISO_8859_5KOI8RMULE_INTERNALUTF8WIN866
WIN1252 WIN1252UTF8
WIN1253 WIN1253UTF8
WIN1254 WIN1254UTF8
WIN1255 WIN1255UTF8
WIN1256 WIN1256UTF8
WIN1257 WIN1257UTF8
WIN1258 WIN1258UTF8

表 23.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

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


23.3.5. 进一步阅读 #

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

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

包含对 EUC_JPEUC_CNEUC_KREUC_TW 的详细解释。

https://www.unicode.org/

Unicode Consortium 的网站。

RFC 3629

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

提交更正

如果您在文档中发现任何不正确的内容,与您对特定功能的体验不符,或者需要进一步澄清,请使用 此表单 报告文档问题。