Postgresql 中文操作指南

24.3. Character Set Support #

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

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

24.3.1. Supported Character Sets #

Table 24.3显示了 PostgreSQL 中可供使用的字符集。

Table 24.3. PostgreSQL Character Sets

Name

Description

Language

Server?

ICU?

Bytes/​Char

Aliases

BIG5

Big Five

Traditional Chinese

No

No

1–2

WIN950, Windows950

EUC_CN

Extended UNIX Code-CN

Simplified Chinese

Yes

Yes

1–3

EUC_JP

Extended UNIX Code-JP

Japanese

Yes

Yes

1–3

EUC_JIS_2004

扩展 UNIX Code-JP,JIS X 0213

Japanese

Yes

No

1–3

EUC_KR

Extended UNIX Code-KR

Korean

Yes

Yes

1–3

EUC_TW

Extended UNIX Code-TW

Traditional Chinese, Taiwanese

Yes

Yes

1–3

GB18030

National Standard

Chinese

No

No

1–4

GBK

Extended National Standard

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

Mule internal code

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

unspecified (see text)

any

Yes

No

1

UHC

Unified Hangul Code

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

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

SQL_ASCII 设置的行为与其他设置的行为有很大不同。当服务器字符集为 SQL_ASCII 时,服务器将按照 ASCII 标准解释字节值 0 至 127,而将字节值 128 至 255 作为未解释的字符。设置 SQL_ASCII 时不会执行任何编码转换。因此,这个设置并不那么明确地声明使用某种特定编码,而只是声明不知道编码。在大多数情况下,如果您使用的是任何非 ASCII 数据,则不建议使用 SQL_ASCII 设置,因为 PostgreSQL 无法通过转换或验证非 ASCII 字符来帮助您。

24.3.2. Setting the Character Set #

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 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)

Important

在大多数现代操作系统上,PostgreSQL 可以确定 LC_CTYPE 设置所暗示的字符集,并且它将强制只使用匹配的数据库编码。在较旧的系统上,您有责任确保您使用的编码与您选择的区域设置预期的一致。此处的错误很可能会导致区域设置相关操作(例如排序)出现奇怪的行为。

即使 LC_CTYPE 不是 CPOSIX,PostgreSQL 也允许超级用户创建使用 SQL_ASCII 编码的数据库。如上所述,SQL_ASCII 并不强制存储在数据库中的数据采用任何特定编码,因此这种选择构成了区域设置相关错误行为的风险。不建议使用此设置组合,将来可能会完全禁止这种组合。

24.3.3. Automatic Character Set Conversion Between Server and Client #

对于许多字符集的组合,PostgreSQL 支持在服务器和客户端之间进行自动字符集转换( Section 24.3.4显示了哪些字符集支持转换)。

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

如果无法转换某个特定字符(假设您针对服务器选择了 EUC_JP 而针对客户端选择了 LATIN1,且返回了一些在 LATIN1 中没有表示的日语字符),则会报告错误。

如果客户端字符集定义为 SQL_ASCII,则无论服务器的字符集是什么,编码转换都会被禁用。(但是,如果服务器的字符集不是 SQL_ASCII,则服务器仍然会检查传入的数据是否针对该编码有效;因此,产生的净效果就像客户端字符集与服务器字符集相同一样。)与服务器一样,除非您使用全 ASCII 数据,否则不建议使用 SQL_ASCII

24.3.4. Available Character Set Conversions #

PostgreSQL 允许在两个字符集之间进行转换,这些字符集的转换函数已列入 pg_conversion 系统目录。PostgreSQL 随附一些预定义转换,如 Table 24.4 中总结所述,并在 Table 24.5 中详细显示。您可使用 SQL 命令 CREATE CONVERSION 创建新转换。(要用于自动的客户端/服务器转换,必须将其字符集对的转换标记为“默认”。)

Table 24.4. Built-in Client/Server Character Set Conversions

Server Character Set

Available Client Character Sets

BIG5

not supported as a server encoding

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

not supported as a server encoding

GBK

not supported as a server encoding

ISO_8859_5

ISO_8859_5KOI8RMULE_INTERNALUTF8WIN866WIN1251

ISO_8859_6

ISO_8859_6, UTF8

ISO_8859_7

ISO_8859_7, UTF8

ISO_8859_8

ISO_8859_8, UTF8

JOHAB

not supported as a server encoding

KOI8R

KOI8RISO_8859_5MULE_INTERNALUTF8WIN866WIN1251

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_INTERNALBIG5EUC_CNEUC_JPEUC_KREUC_TWISO_8859_5KOI8RLATIN1LATIN4SJISWIN866WIN1250WIN1251

SJIS

not supported as a server encoding

SHIFT_JIS_2004

not supported as a server encoding

SQL_ASCII

any (no conversion will be performed)

UHC

not supported as a server encoding

UTF8

all supported encodings

WIN866

WIN866ISO_8859_5KOI8RMULE_INTERNALUTF8WIN1251

WIN874

WIN874, UTF8

WIN1250

WIN1250, LATIN2, MULE_INTERNAL, UTF8

WIN1251

WIN1251ISO_8859_5KOI8RMULE_INTERNALUTF8WIN866

WIN1252

WIN1252, UTF8

WIN1253

WIN1253, UTF8

WIN1254

WIN1254, UTF8

WIN1255

WIN1255, UTF8

WIN1256

WIN1256, UTF8

WIN1257

WIN1257, UTF8

WIN1258

WIN1258, UTF8

Table 24.5. All Built-in Character Set Conversions

Conversion Name #ftn.id-1.6.11.5.8.4.2.4.1.1.1

Source Encoding

Destination Encoding

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

[id="a",role="bare"]#id-1.6.11.5.8.4.2.4.1.1.1 [id="a"] 转换名称遵循标准命名方案:源编码的正式名称(所有非字母数字字符替换为下划线),后跟 to ,后跟同样处理后的目标编码名称。因此,这些名称有时会与 Table 24.3 中所示的惯例编码名称不同。

24.3.5. Further Reading #

这些是开始了解各种编码系统的好资料。

  • CJKV Information Processing: Chinese, Japanese, Korean & Vietnamese Computing

    • 包含 EUC_JPEUC_CNEUC_KREUC_TW 的详细说明。

  • https://www.unicode.org/

    • Unicode 联盟的网站。

  • RFC 3629

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