©
本文档使用 PHP中文网手册 发布
PostgreSQL 能够以各种字符集存储文本, 比如 ISO-8859 系列和EUC(扩展 Unix 编码)、UTF-8 、Mule 国际编码。 所有字符集都可以在服务器上透明地使用。 如果你使用了来自其它数据源的扩展函数, 那么它取决于他们是否正确地书写了代码。 缺省的字符集是在使用 initdb 初始化数据库集群的时候选择的。 在你创建数据库的时候是可以覆盖这个缺省的。 因此,你可以有多个数据库,每个都有不同的字符集。
An important restriction, however, is that each database's character set must be compatible with the database's LC_CTYPE (character classification) and LC_COLLATE (string sort order) locale settings. For C or POSIX locale, any character set is allowed, but for other locales there is only one character set that will work correctly. (On Windows, however, UTF-8 encoding can be used with any locale.)
一项重要的限制是每个数据库的字节设置必须被数据库的LC_CTYPE(字节分类)和 LC_COLLATE(字符串存储命令)区域设置兼容。 对于C或者POSIX区域,任何字符设置都是被允许的,但是对于其它区域仅仅只可以设置一种字符才可以正常工作。 (在windows操作系统,UTF-8编码可以在任何一个区域使用。)
Table 22-1 显示了可以用在 PostgreSQL上的编码。
Table 22-1. PostgreSQL服务器字符集
名称 | 描述 | 语言 | 服务端 | 字节/字符 | 别名 |
---|---|---|---|---|---|
BIG5 | 大五码 | 繁体中文 | No | 1-2 | WIN950, Windows950 |
EUC_CN | 拓展UNIX代码——Cn | 简体中文 | Yes | 1-3 | |
EUC_JP | 扩展UNIX代码-JP | 日文 | Yes | 1-3 | |
EUC_JIS_2004 | 扩展UNIX代码-JP,JIS x 0213 | 日文 | Yes | 1-3 | |
EUC_KR | 扩展UNIX代码-KR | 韩文 | Yes | 1-3 | |
EUC_TW | 扩展UNIX代码-TW | 繁体中文,台湾 | Yes | 1-3 | |
GB18030 | 国标码 | 中文 | No | 1-2 | |
GBK | 扩展国标码 | 简体中文 | No | 1-2 | WIN936, Windows936 |
ISO_8859_5 | ISO 8859-5, ECMA 113 | 拉丁/西里尔语 | Yes | 1 | |
ISO_8859_6 | ISO 8859-6, ECMA 114 | 拉丁/阿拉伯语 | Yes | 1 | |
ISO_8859_7 | ISO 8859-7, ECMA 118 | 拉丁/希腊语 | Yes | 1 | |
ISO_8859_8 | ISO 8859-8, ECMA 121 | 拉丁/希伯莱语 | Yes | 1 | |
JOHAB | JOHAB | 韩语 | No | 1-3 | |
KOI8R | KOI8-R | 西里尔语 | Yes | 1 | KOI8 |
KOI8U | KOI8-U | 乌克兰语 | Yes | 1 | |
LATIN1 | ISO 8859-1, ECMA 94 | 西欧语 | Yes | 1 | ISO88591 |
LATIN2 | ISO 8859-2, ECMA 94 | 中欧语 | Yes | 1 | ISO88592 |
LATIN3 | ISO 8859-3, ECMA 94 | 南欧语 | Yes | 1 | ISO88593 |
LATIN4 | ISO 8859-4, ECMA 94 | 北欧语 | Yes | 1 | ISO88594 |
LATIN5 | ISO 8859-9, ECMA 128 | 土耳其语 | Yes | 1 | ISO88599 |
LATIN6 | ISO 8859-10, ECMA 144 | 日耳曼语 | Yes | 1 | ISO885910 |
LATIN7 | ISO 8859-13 | 波罗的海语 | Yes | 1 | ISO885913 |
LATIN8 | ISO 8859-14 | 凯尔特语 | Yes | 1 | ISO885914 |
LATIN9 | ISO 8859-15 | 带有欧洲语系和语调的 LATIN1 | Yes | 1 | ISO885915 |
LATIN10 | ISO 8859-16, ASRO SR 14111 | 罗马尼亚语 | Yes | 1 | ISO885916 |
MULE_INTERNAL | 国际编码 | 多语种 Emacs | Yes | 1-4 | |
SJIS | Shift JIS | 日语 | No | 1-2 | Mskanji, ShiftJIS, WIN932, Windows932 |
SHIFT_JIS_2004 | Shift JIS, JIS X 0213 | 日语 | No | 1-2 | |
SQL_ASCII | 未声明(见文本) | 任意 | Yes | 1 | |
UHC | 统一韩语编码 | 韩语 | No | 1-2 | WIN949, Windows949 |
UTF8 | Unicode, 8-bit | 全部 | Yes | 1-4 | Unicode |
WIN866 | Windows CP866 | 西里尔语 | Yes | 1 | ALT |
WIN874 | Windows CP874 | 泰国语 | Yes | 1 | |
WIN1250 | Windows CP1250 | 中欧语 | Yes | 1 | |
WIN1251 | Windows CP1251 | 西里尔语 | Yes | 1 | WIN |
WIN1252 | Windows CP1252 | 西欧语 | Yes | 1 | |
WIN1253 | Windows CP1253 | 希腊语 | Yes | 1 | |
WIN1254 | Windows CP1254 | 土耳其语 | Yes | 1 | |
WIN1255 | Windows CP1255 | 希伯来语 | Yes | 1 | |
WIN1256 | Windows CP1256 | 阿拉伯语 | Yes | 1 | |
WIN1257 | Windows CP1257 | 波罗的语 | Yes | 1 | |
WIN1258 | Windows CP1258 | 越南语 | Yes | 1 | ABC, TCVN, TCVN5712, VSCII |
并非所有的客户端的 API都支持列出的编码。例如 PostgreSQL JDBC 驱动 就不支持 MULE_INTERNAL, LATIN6, LATIN8, and LATIN10。
SQL_ASCII 设置与其它设置表现得相当不同。 如果服务器字符集是 SQL_ASCII, 服务器把字节值 0-127 的数值根据 ASCII 标准解析 而字节值 128-255 的则当作未解析的字符。 如果设置为SQL_ASCII. 就不会有编码转换。 因此,这个设置基本不用来声明所使用的编码,因为这个声明会忽略编码。 在大多数情况下,如果你使用了任何非 ASCII 数据,那么使用 SQL_ASCII 设置都是不明智的,因为 PostgreSQL 会无法帮助你转换或者校验非 ASCII 字符。
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 21.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设置,它会在匹配数据库编码时运行。 在比较老的操作系统上,你的任务是保证你用到的编码是你选择的区域所预期的。这个区域的 的一个错误可能会导致locale-dependent的错误行为。
PostgreSQL将会允许超级用户用SQL_ASCII编码创建数据库,即使 LC_CTYPE不是C或POSIX。就像上面注意到的, SQL_ASCII不执行那些在数据库里有特别编码的数据存储,这个选择构成locale-dependent发生错误行为的风险。 使用这些组合的设置已经过时,或者某一天可能被禁止。
PostgreSQL 支持在服务器和前端之间的自动编码转换。 转换信息在系统表pg_conversion中存储。 PostgreSQL带着一些预定义的转换。 它们在Table 22-2中列出。 你可以使用 SQL 命令CREATE CONVERSION创建一个新的转换。
Table 22-2. 客户/服务器字符集转换
服务器字符集 | 可用客户端字符集 |
---|---|
BIG5 | 不支持做服务器端编码 |
EUC_CN | EUC_CN, MULE_INTERNAL, UTF8 |
EUC_JP | EUC_JP, MULE_INTERNAL, SJIS, UTF8 |
EUC_KR | EUC_KR, MULE_INTERNAL, UTF8 |
EUC_TW | EUC_TW, BIG5, MULE_INTERNAL, UTF8 |
GB18030 | 不支持做服务器端编码 |
GBK | 不支持做服务器端编码 |
ISO_8859_5 | ISO_8859_5, KOI8R, MULE_INTERNAL, UTF8, WIN866, WIN1251 |
ISO_8859_6 | ISO_8859_6, UTF8 |
ISO_8859_7 | ISO_8859_7, UTF8 |
ISO_8859_8 | ISO_8859_8, UTF8 |
JOHAB | JOHAB, UTF8 |
KOI8R | KOI8R, ISO_8859_5, MULE_INTERNAL, UTF8, WIN866, WIN1251 |
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_INTERNAL, BIG5, EUC_CN, EUC_JP, EUC_KR, EUC_TW, ISO_8859_5, KOI8R, LATIN1 to LATIN4, SJIS, WIN866, WIN1250, WIN1251 |
SJIS | 不支持做服务器端编码 |
SQL_ASCII | 任意(不会发生编码转换) |
UHC | 不支持做服务器端编码 |
UTF8 | 所有支持的编码 |
WIN866 | WIN866, ISO_8859_5, KOI8R, MULE_INTERNAL, UTF8, WIN1251 |
WIN874 | WIN874, UTF8 |
WIN1250 | WIN1250, LATIN2, MULE_INTERNAL, UTF8 |
WIN1251 | WIN1251, ISO_8859_5, KOI8R, MULE_INTERNAL, UTF8, WIN866 |
WIN1252 | WIN1252, UTF8 |
WIN1253 | WIN1253, UTF8 |
WIN1254 | WIN1254, UTF8 |
WIN1255 | WIN1255, UTF8 |
WIN1256 | WIN1256, UTF8 |
WIN1257 | WIN1257, UTF8 |
WIN1258 | WIN1258, UTF8 |
要想打开自动字符集转换功能,你必须告诉PostgreSQL你想在客户端使用的字符集(编码)。你可以用好几种方法实现这个目的。
用psql里的\encoding 命令\encoding允许你动态修改客户端编码。 比如,把编码改变为SJIS 键入:
\encoding SJIS
libpq (Section 31.9) has functions to control the client encoding.
使用libpq (Section 31.9) 具有控制客户端编码的功能。
使用 SET client_encoding TO. 设置客户端编码:
SET CLIENT_ENCODING TO 'value';
你还可以把 SQL 语法里的x SET NAMES 用于这个目的:
SET NAMES 'value';
查询当前客户端编码:
SHOW client_encoding;
返回缺省编码:
RESET client_encoding;
使用 PGCLIENTENCODING. 如果在客户端的环境里定义了 PGCLIENTENCODING 环境变量,那么在与服务器进行连接时将自动选择客户端编码。这个编码随后可以用上面谈到的任何其它方法覆盖。
使用 client_encoding配置变量。 如果在client_encoding 里设置了该变量, 那么在与服务器建立了连接之后,这个客户端编码将自动选定。这个设置随后可以被上面提到的其它方法覆盖。
假如无法进行特定的字符转换,比如,你选的服务器编码是EUC_JP 而客户端是LATIN1 那么有些日文字符不能转换成 LATIN1; 这时将报告错误。
如果客户端字符集定义成了SQL_ASCII, 那么编码转换会被关闭,不管服务器的字符集是什么都一样。和服务器一样,除非你的工作环境全部是 ASCII 数据,否则使用 SQL_ASCII is unwise是不明智的。
下面是学习各种类型的编码系统的好地方。
一整套有关字符集,编码以及代码页的文档。
详细地解释了第3.2节出现的 EUC_JP, EUC_CN, EUC_KR, EUC_TW编码。
Unicode的主页。
UTF-8 的定义