PostgreSQL 里面的字符集支持你能够以各种字符集存储文本, 包括单字节的字符集,比如 ISO 8859 系列和 EUC (扩展 Unix 编码 Extended Unix Code),Unicode 和 Mule 国际编码。所有字符集都可以在服务器上透明地使用。 (如果你使用了来自其它数据源地扩展函数,那么它取决于他们是否正确地书写了代码。) 缺省的字符集是在使用 initdb 初始化你的 PostgreSQL 数据库集群的时候选择的。 在你的使用 createdb 或者 SQL 命令 CREATE DATABASE 的时候是可以覆盖这个缺省的。因此,你可以有多个数据库,每个都有不同的字符集。
Table 20-1 显示了可以用在服务器的字符集。
Table 20-1. 服务器字符集
名字 | 描述 |
---|---|
SQL_ASCII | ASCII |
EUC_JP | 日文 EUC |
EUC_CN | 中文 EUC |
EUC_KR | 韩文 EUC |
JOHAB | 韩文 EUC (Hangle base) |
EUC_TW | 台湾 EUC |
UNICODE | Unicode(UTF-8) |
MULE_INTERNAL | Mule 内部编码 |
LATIN1 | ISO 8859-1/ECMA 94 (Latin Alphabet No.1) |
LATIN2 | ISO 8859-2/ECMA 94 (Latin Alphabet No.2) |
LATIN3 | ISO 8859-3/ECMA 94 (Latin Alphabet No.3) |
LATIN4 | ISO 8859-4/ECMA 94 (Latin Alphabet No.4) |
LATIN5 | ISO 8859-9/ECMA 128 (Latin Alphabet No.5) |
LATIN6 | ISO 8859-10/ECMA 144 (Latin Alphabet No.6) |
LATIN7 | ISO 8859-13 (Latin Alphabet no.7) |
LATIN8 | ISO 8859-14 (Latin Alphabet no.8) |
LATIN9 | ISO 8859-15 (Latin Alphabet no.9) |
LATIN10 | ISO 8859-16/ASRO SR 14111 (Latin Alphabet no.10) |
ISO_8859_5 | ISO 8859-5/ECMA 113 (Latin/Cyrillic) |
ISO_8859_6 | ISO 8859-6/ECMA 114 (Latin/Arabic) |
ISO_8859_7 | ISO 8859-7/ECMA 118 (Latin/Greek) |
ISO_8859_8 | ISO 8859-8/ECMA 121 (Latin/Hebrew) |
KOI8 | KOI8-R(U) |
ALT | Windows CP866 |
WIN874 | Windows CP874 (Thai) |
WIN1250 | Windows CP1250 |
WIN | Windows CP1251 |
WIN1256 | Windows CP1256 (Arabic) |
TCVN | TCVN-5712/Windows CP1258 (Vietnamese) |
Important: 在 PostgreSQL7.2 之前, LATIN5错误地表示 ISO 8859-5 的意思。 从 7.2 开始 LATIN5表示 ISO8859-9。 如果你有一个在 7.1 或者之前创建的使用了 LATIN5的数据库, 而且你希望移植到 7.2(或者以后的版本), 那么你必须非常仔细地注意这个变化。
并非所有API支持上面列出的编码。比如, PostgreSQL JDBC 驱动就不支持MULE_INTERNAL, LATIN6,LATIN8 和 LATIN10。
initdb 为一个 PostgreSQL 集群定义缺省的字符集,比如:
initdb -E EUC_JP
把缺省字符集设置为 EUC_JP (用于日文的扩展的 Unix 编码)。 如果你喜欢用长选项声明的话,你可以用 --encoding 代替 -E。 如果没有给出-E或者--encoding选项, 则使用SQL_ASCII。
你可以创建一个有着不同编码的数据库:
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 regression | t-ishii | SQL_ASCII template1 | t-ishii | EUC_JP test | t-ishii | EUC_JP unicode | t-ishii | UNICODE (9 rows)
Important: 虽然你可以给一个数据库声明你需要的任何编码,但选择一个与你选择的区域不一致的编码还是不妥的做法。 LC_COLLATE 和 LC_CTYPE 设置暗示一个特定的编码, 与区域相关的操作(比如排序)在不兼容的编码里很有可能产生错误的解析。
因为这些区域设置都是由 initdb 冻结的, 所以在不同的数据库里使用不同的编码更多是理论而不是现实。 这些机制很有可能在将来版本的 PostgreSQL 得到改进。
一个安全使用多种编码的方法是在 initdb 的时候把区域设置为 C 或者 POSIX,这样旧关闭了任何实际的区域敏感性。
PostgreSQL 支持一些编码在服务器和前端之间的自动编码转换。 转换信息在系统表 pg_conversion 中存储。 你可以使用 SQL 命令 CREATE CONVERSION 创建一个新的转换。 PostgreSQL带着一些预定义的转换。它们在 Table 20-2 中列出。
Table 20-2. 客户/服务器字符集转换
服务器字符集 | 可用客户端字符集 |
---|---|
SQL_ASCII | SQL_ASCII, UNICODE, MULE_INTERNAL |
EUC_JP | EUC_JP, SJIS, UNICODE, MULE_INTERNAL |
EUC_CN | EUC_CN, UNICODE, MULE_INTERNAL |
EUC_KR | EUC_KR, UNICODE, MULE_INTERNAL |
JOHAB | JOHAB, UNICODE |
EUC_TW | EUC_TW, BIG5, UNICODE, MULE_INTERNAL |
LATIN1 | LATIN1, UNICODE, MULE_INTERNAL |
LATIN2 | LATIN2, WIN1250, UNICODE, MULE_INTERNAL |
LATIN3 | LATIN3, UNICODE, MULE_INTERNAL |
LATIN4 | LATIN4, UNICODE, MULE_INTERNAL |
LATIN5 | LATIN5, UNICODE |
LATIN6 | LATIN6, UNICODE, MULE_INTERNAL |
LATIN7 | LATIN7, UNICODE, MULE_INTERNAL |
LATIN8 | LATIN8, UNICODE, MULE_INTERNAL |
LATIN9 | LATIN9, UNICODE, MULE_INTERNAL |
LATIN10 | LATIN10, UNICODE, MULE_INTERNAL |
ISO_8859_5 | ISO_8859_5, UNICODE, MULE_INTERNAL, WIN, ALT, KOI8 |
ISO_8859_6 | ISO_8859_6, UNICODE |
ISO_8859_7 | ISO_8859_7, UNICODE |
ISO_8859_8 | ISO_8859_8, UNICODE |
UNICODE | EUC_JP, SJIS, EUC_KR, UHC, JOHAB, EUC_CN, GBK, EUC_TW, BIG5, LATIN1 到 LATIN10, ISO_8859_5, ISO_8859_6, ISO_8859_7, ISO_8859_8, WIN, ALT, KOI8, WIN1256, TCVN, WIN874, GB18030, WIN1250 |
MULE_INTERNAL | EUC_JP, SJIS, EUC_KR, EUC_CN, EUC_TW, BIG5, LATIN1 到 LATIN5, WIN, ALT, WIN1250 BIG5, ISO_8859_5, KOI8 |
KOI8 | ISO_8859_5, WIN, ALT, KOI8, UNICODE, MULE_INTERNAL |
ALT | ISO_8859_5, WIN, ALT, KOI8, UNICODE, MULE_INTERNAL |
WIN | ISO_8859_5, WIN, ALT, KOI8, UNICODE, MULE_INTERNAL |
WIN874 | WIN874, UNICODE |
WIN1250 | LATIN2, WIN1250, UNICODE, MULE_INTERNAL |
WIN | ISO_8859_5, WIN, ALT, KOI8, UNICODE, MULE_INTERNAL |
WIN1256 | WIN1256, UNICODE |
TCVN | TCVN, UNICODE |
要想打开自动字符集转换功能,你必须告诉 PostgreSQL 你想在客户端使用的字符集(编码)。你可以用好几种方法实现这个目的。
用 psql 里的 \encoding 命令。 \encoding 允许你动态修改客户端编码。 比如,把编码改变为 SJIS,键入:
\encoding SJIS
使用 libpq 函数。 \encoding 在做此用途的时候实际上是调用 PQsetClientEncoding()。
int PQsetClientEncoding(PGconn *conn, const char *encoding);
这里 conn 与后端的联接,而 encoding 是你想用的编码。如果编码设置成功它返回 0,否则返回 -1。本次联接的当前编码可以用下面函数显示:
int PQclientEncoding(const PGconn *conn);
请注意它只返回编码 ID,而不是象 EUC_JP 这样的编码符号字串。 要把编码 ID 转换为编码符号,你可以用:
char *pg_encoding_to_char(int encoding_id);
使用 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配置变量。 如果在 postgresql.conf 里设置了 client_encoding 变量, 那么在与服务器建立了联接之后,这个客户端编码将自动选定。(这个设置随后可以被上面提到 的其他方法覆盖。)
假如无法进行特定的字符转换 — 比如, 你选的服务器编码是EUC_JP, 客户端是LATIN1,那么有些日文字符不能转换成LATIN1。这时, 不能用LATIN1字符集表示的字母将被转换成圆括弧包围的十六进制,像,(826C) 这样。
下面是学习各种类型的编码系统的好地方。
详细地解释了第3.2节出现的EUC_JP, EUC_CN,EUC_KR,EUC_TW。
Unicode 的家目录。
定义了UTF-8。