PostgreSQL 8.2.3 中文文档
后退快退章21. 区域快进前进

21.2. 字符集支持

PostgreSQL 能够以各种字符集存储文本,比如 ISO-8859 系列和 EUC(扩展 Unix 编码)、UTF-8 、Mule 国际编码。所有字符集都可以在服务器上透明地使用。如果你使用了来自其它数据源的扩展函数,那么它取决于他们是否正确地书写了代码。缺省的字符集是在使用 initdb 初始化数据库集群的时候选择的。在你创建数据库的时候是可以覆盖这个缺省的。因此,你可以有多个数据库,每个都有不同的字符集。

21.2.1. 支持的字符集编码

表21-1 显示了可以用在服务器的字符集。

表21-1. PostgreSQL 服务器字符集

名字描述语言服务端?字节/字符别名
BIG5大五码繁体中文No1-2WIN950, Windows950
EUC_CN扩展UNIX代码-CN简体中文Yes1-3 
EUC_JP扩展UNIX代码-JP日文Yes1-3 
EUC_KR扩展UNIX代码-KR韩文Yes1-3 
EUC_TW扩展UNIX代码-TW繁体中文,台湾Yes1-3 
GB18030国标码中文No1-2 
GBK扩展国标码简体中文No1-2WIN936, Windows936
ISO_8859_5ISO 8859-5, ECMA 113拉丁/西里尔语Yes1 
ISO_8859_6ISO 8859-6, ECMA 114拉丁/阿拉伯语Yes1 
ISO_8859_7ISO 8859-7, ECMA 118拉丁/希腊语Yes1 
ISO_8859_8ISO 8859-8, ECMA 121拉丁/希伯莱语Yes1 
JOHABJOHAB韩语Yes1-3 
KOI8KOI8-R(U)西里尔语Yes1KOI8R
LATIN1ISO 8859-1, ECMA 94西欧语Yes1ISO88591
LATIN2ISO 8859-2, ECMA 94中欧语Yes1ISO88592
LATIN3ISO 8859-3, ECMA 94南欧语Yes1ISO88593
LATIN4ISO 8859-4, ECMA 94北欧语Yes1ISO88594
LATIN5ISO 8859-9, ECMA 128土耳其语Yes1ISO88599
LATIN6ISO 8859-10, ECMA 144日耳曼语Yes1ISO885910
LATIN7ISO 8859-13波罗的海语Yes1ISO885913
LATIN8ISO 8859-14凯尔特语Yes1ISO885914
LATIN9ISO 8859-15带有欧洲语系和语调的 LATIN1Yes1ISO885915
LATIN10ISO 8859-16, ASRO SR 14111罗马尼亚语Yes1ISO885916
MULE_INTERNALMule 国际编码多语种 EmacsYes1-4 
SJISShift JIS日语No1-2Mskanji, ShiftJIS, WIN932, Windows932
SQL_ASCII未声明(见文本)任意Yes1 
UHC统一韩语编码韩语No1-2WIN949, Windows949
UTF8Unicode, 8-bit全部Yes1-4Unicode
WIN866Windows CP866西里尔语Yes1ALT
WIN874Windows CP874泰国语Yes1 
WIN1250Windows CP1250中欧语Yes1 
WIN1251Windows CP1251西里尔语Yes1WIN
WIN1252Windows CP1252西欧语Yes1 
WIN1253Windows CP1253希腊语Yes1 
WIN1254Windows CP1254土耳其语Yes1 
WIN1255Windows CP1255希伯来语Yes1 
WIN1256Windows CP1256阿拉伯语Yes1 
WIN1257Windows CP1257波罗的语Yes1 
WIN1258Windows CP1258越南语Yes1ABC, TCVN, TCVN5712, VSCII

并非所有API都支持上面列出的编码。比如,PostgreSQL JDBC驱动就不支持 MULE_INTERNAL, LATIN6, LATIN8, LATIN10

SQL_ASCII 设置与其它设置表现得相当不同。如果服务器字符集是 SQL_ASCII ,服务器把字节值 0-127 的数值根据 ASCII 标准解析,而字节值 128-255 的则当作未解析的字符。如果设置为 SQL_ASCII 就不会有编码转换。因此,这个设置基本不用来声明所使用的编码,因为这个声明会忽略编码。在大多数情况下,如果你使用了任何非 ASCII 数据,那么使用 SQL_ASCII 设置都是不明智的,因为 PostgreSQL 会无法帮助你转换或者校验非 ASCII 字符。

21.2.2. 设置字符集

initdb 为一个 PostgreSQL 集群定义缺省的字符集,比如:

initdb -E EUC_JP

把缺省字符集设置为 EUC_JP(用于日文的扩展 Unix 编码)。如果你喜欢用长选项声明的话,可以用 --encoding 代替 -E 选项。如果没有给出 -E--encoding 选项,initdb 将基于制定的区域或者缺省区域试图判断合适的编码。

你可以创建一个有着不同编码的数据库:

createdb -E EUC_KR korean

将创建一个使用 EUC_KR 字符集的名字叫 korean 的数据库。另外一种实现方法是使用 SQL 命令:

CREATE DATABASE korean WITH ENCODING 'EUC_KR';

数据库的编码是存储在 pg_database 系统表中的。你可以用 psql-l 选项或 \l 命令列出这些编码。

$ psql -l
            List of databases
   Database    |  Owner  |   Encoding    
---------------+---------+---------------
 euc_cn        | t-ishii | EUC_CN
 euc_jp        | t-ishii | EUC_JP
 euc_kr        | t-ishii | EUC_KR
 euc_tw        | t-ishii | EUC_TW
 mule_internal | t-ishii | MULE_INTERNAL
 postgres      | t-ishii | EUC_JP
 regression    | t-ishii | SQL_ASCII
 template1     | t-ishii | EUC_JP
 test          | t-ishii | EUC_JP
 utf8          | t-ishii | UTF8
(9 rows)

【重要】虽然你可以给一个数据库声明你需要的任何编码,但选择一个与你选择的区域不一致的编码还是不妥的做法。LC_COLLATELC_CTYPE 设置暗示一个特定的编码,与区域相关的操作(比如排序)在不兼容的编码里很有可能产生错误的解析。

因为这些区域设置都是由 initdb 冻结的,所以在不同的数据库里使用不同的编码更多是理论而不是现实。这些机制很有可能在将来版本的 PostgreSQL 得到改进。

一个安全使用多种编码的方法是在 initdb 的时候把区域设置为 CPOSIX ,这样就关闭了任何实际的区域敏感性。

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

PostgreSQL 支持在服务器和前端之间的自动编码转换。转换信息在系统表 pg_conversion 中存储。PostgreSQL 带着一些预定义的转换。它们在表21-2中列出。你可以使用 SQL 命令 CREATE CONVERSION 创建一个新的转换。

表21-2. 客户/服务器字符集转换

服务器字符集可用客户端字符集
BIG5不支持做服务器端编码
EUC_CNEUC_CN, MULE_INTERNAL, UTF8
EUC_JPEUC_JP, MULE_INTERNAL, SJIS, UTF8
EUC_KREUC_KR, MULE_INTERNAL, UTF8
EUC_TWEUC_TW, BIG5, MULE_INTERNAL, UTF8
GB18030不支持做服务器端编码
GBK不支持做服务器端编码
ISO_8859_5ISO_8859_5, KOI8, MULE_INTERNAL, UTF8, WIN866, WIN1251
ISO_8859_6ISO_8859_6, UTF8
ISO_8859_7ISO_8859_7, UTF8
ISO_8859_8ISO_8859_8, UTF8
JOHABJOHAB, UTF8
KOI8KOI8, ISO_8859_5, MULE_INTERNAL, UTF8, WIN866, WIN1251
LATIN1LATIN1, MULE_INTERNAL, UTF8
LATIN2LATIN2, MULE_INTERNAL, UTF8, WIN1250
LATIN3LATIN3, MULE_INTERNAL, UTF8
LATIN4LATIN4, MULE_INTERNAL, UTF8
LATIN5LATIN5, UTF8
LATIN6LATIN6, UTF8
LATIN7LATIN7, UTF8
LATIN8LATIN8, UTF8
LATIN9LATIN9, UTF8
LATIN10LATIN10, UTF8
MULE_INTERNALMULE_INTERNAL, BIG5, EUC_CN, EUC_JP, EUC_KR, EUC_TW, ISO_8859_5, KOI8, LATIN1 to LATIN4, SJIS, WIN866, WIN1250, WIN1251
SJIS不支持做服务器端编码
SQL_ASCII任意(不会发生编码转换)
UHC不支持做服务器端编码
UTF8所有支持的编码
WIN866WIN866, ISO_8859_5, KOI8, MULE_INTERNAL, UTF8, WIN1251
WIN874WIN874, UTF8
WIN1250WIN1250, LATIN2, MULE_INTERNAL, UTF8
WIN1251WIN1251, ISO_8859_5, KOI8, MULE_INTERNAL, UTF8, WIN866
WIN1252WIN1252, UTF8
WIN1253WIN1253, UTF8
WIN1254WIN1254, UTF8
WIN1255WIN1255, UTF8
WIN1256WIN1256, UTF8
WIN1257WIN1257, UTF8
WIN1258WIN1258, UTF8

要想打开自动字符集转换功能,你必须告诉 PostgreSQL 你想在客户端使用的字符集(编码)。你可以用好几种方法实现这个目的。

假如无法进行特定的字符转换,比如,你选的服务器编码是 EUC_JP 而客户端是 LATIN1 ,那么有些日文字符不能转换成 LATIN1 。这时将报告错误。

如果客户端字符集定义成了 SQL_ASCII ,那么编码转换会被关闭,不管服务器的字符集是什么都一样。和服务器一样,除非你的工作环境全部是 ASCII 数据,否则使用 SQL_ASCII 是不明智的。

21.2.4. 进一步阅读

下面是学习各种类型的编码系统的好地方。

http://www.i18ngurus.com/docs/984813247.html

一整套有关字符集,编码以及代码页的文档。

ftp://ftp.ora.com/pub/examples/nutshell/ujip/doc/cjk.inf

详细地解释了第3.2节出现的 EUC_JP, EUC_CN, EUC_KR, EUC_TW 编码。

http://www.unicode.org/

Unicode 的主页。

RFC 2044

UTF-8 的定义。


后退首页前进
区域支持上一级日常数据库维护工作