Chapter 5. 区域

Table of Contents
5.1. 区域支持
5.1.1. 概述
5.1.2. 益处
5.1.3. 问题
5.2. 多字节支持
5.2.1. 支持字符集编码
5.2.2. 设置编码
5.2.3. 服务器和客户端之间的自动编码转换
5.2.4. 如果不能转换会怎样?
5.2.5. 参考
5.2.6. 历史
5.2.7. Windows/ODBC 里的 WIN1250
5.3. 单字节字符集记录

从管理员的角度描述可用的区域特性.

PostgreSQL 通过三种途径支持区域:

5.1. 区域支持

区域支持指的是应用中考虑字母,排序,数字格式化 等与文化相关的问题. PostgreSQL 使用服务器操作系统提供的标准 ISO C 和类似POSIX的区域机制. 更多的信息请参考你的系统的文档.

5.1.1. 概述

区域支持是 在使用 initdb 创建一个数据库集群的时候自动初始化的. initdb 将会按照它的执行环境的区域设置初始化 数据库集群;因此如果你的系统已经设置为你的数据库集群想要的区域, 那么你就没有什么可干的.如果你想使用其它的区域(或者你还不知道 你的系统设置的区域是什么),那么你可以用 --locale 告诉 initdb 你需要的区域究竟是哪个. 比如∶

$ initdb --locale=sv_SE

这个例子就把区域设置为瑞典(sv),用瑞典语说话 (SE).其他的可能性是 en_US(美国英语)和 fr_CA (加拿大法语). 如果有多于一种字符集可以用于区域,那么声明看起来象下面这样: cs_CZ.ISO8859-2.你的系统里有哪些可用的区域设置,它们的名字 是什么,这些信息都取决于你的操作系统提供商提供了什么 以及你安装了什么东西.

有时候,把几种区域规则混合起来也很有用,比如,使用美国字符规则 而用西班牙语信息.为了支持这些,我们有一套区域子范畴用于控制区域规则 的某一方面.

LC_COLLATE字符串排序顺序
LC_CTYPE字符分类(什么是字母?什么是这个字母的等效大写?)
LC_MESSAGES信息的语言
LC_MONETARY货币金额的格式
LC_NUMERIC数字的格式
LC_TIME日期和时间的格式

这些范畴名转换成 initdb 选项的名字以 覆盖某个特定范畴的区域选择.比如,要把区域设置为加拿大法语, 但使用 U.S. 规则进行货币格式化,可以使用 initdb --locale=fr_CA --lc-monetary=en_US

如果你想要你的系统表现得象没有区域支持,那么使用特殊的区域 CPOSIX

一些区域范畴的性质是它们的值必需在数据库集群的生命期内固定. 也就是说,一旦运行了 initdb,你就再也不能 更改它们了.LC_COLLATELC_CTYPE 就是这样的范畴.它们影响索引的排序顺序,因此它们必需保持固定, 否则在文本字段上的索引将会崩溃.PostgreSQL 通过记录 initdb 看到的 LC_COLLATELC_CTYPE 来强迫这一点. 服务器在启动的时候自动使用这两个数值.

其它区域范畴可以在服务器启动的时候根据需要设置运行时配置变量 来改变(参阅 Section 3.4 获取细节). initdb 选择的缺省值实际上只是做为服务器 运行缺省写入配置文件 postgresql.conf. 如果你在 postgresql.conf 里面删除了 相应的赋值,那么服务器将会继承来自运行环境的设置.

请注意服务器的区域行为是由它看到的环境变量决定的,而不是由任何客户端 的环境变量影响的.因此,我们要在启动服务器之前认真地设置好这些变量. 这样带来的一种情况是如果客户端和服务器设置成不同的区域, 那么消息可能以不同的语言呈现,实际情况取决于它们的源是什么.

注意: 在我们谈到从执行环境继承区域的时候,我们的意思是在大多数操作系统上的 下列动作∶对于一个给定的区域范畴,比如字符集,按照下面的顺序评估 这些环境变量,直到找到一个设置了的∶LC_ALLLC_COLLATE(变量对应相应的范畴), LANG.如果这些环境变量一个都没有设置,那么 区域缺省为 C

一些信息区域化库也使用环境变量 LANGUAGE, 它覆盖所有其它用于设置语言信息的区域设置.如果有问题, 请参考你的操作系统的文档,特别是 gettext 手册页获取更多信息.

要打开用户选择的信息翻译,我们必需使用 --enable-nls 选项.这个选项独立于其它区域支持.

5.1.2. 益处

区域支持特别影响下面的特性:

  • ORDER BY 查询里的排序顺序.

  • 函数里的 to_char家族

  • 模式匹配中的 LIKE~ 操作符

PostgreSQL 里区域支持的唯一的严重缺点是速度.因此 只有你需要的时候才使用它. 同时我们还要特别指出的是选择一个非 C 区域设置将关闭为 LIKE~ 操作符设置的索引优化, 这样对那些使用这些操作符的搜索可能有巨大的性能影响.

5.1.3. 问题

如果经过上面解释后区域支持仍然不能运转,那你就要检查一下看看 你的操作系统的区域支持是否正确配置. 要检查某个区域是否安装并且正常运转,你可以使用象 Perl 这样的工具.Perl 也支持区域,而且如果区域破损了,perl -v 会发出类似下面的抱怨:

$ export LC_CTYPE='not_exist'
$ perl -v
perl: warning: Setting locale failed.
perl: warning: Please check that your locale settings:
LC_ALL = (unset),
LC_CTYPE = "not_exist",
LANG = (unset)
are supported and installed on your system.
perl: warning: Falling back to the standard locale ("C").

检查你的区域文件是否在正确位置.可能的位置包括: /usr/lib/localeLinuxSolaris), /usr/share/localeLinux), /usr/lib/nls/locDUX 4.0).如果你 不知道在那里,请检查你的系统的手册页.

请检查核实 PostgreSQL 确实使用了你认为它该用的 区域设置.LC_COLLATELC_CTYPE 设置都是 在 initdb 的时候决定的,如果不重复 initdb 是不可能改变的.其它的区域设置包括 LC_MESSAGESLC_MONETARY 都是由 postmaster 启动的环境决定的, 可以通过简单地重启来修改.你可以用 contrib/pg_controldata 工具程序 检查数据库的 LC_COLLATELC_CTYPE 的设置.

目录 src/test/locale 包含 PostgreSQL 的区域支持的测试套件.

那些通过分析错误信息处理服务器端错误的客户端应用很明显 会有问题,因为服务器来的信息可能会是以不同语言表示的. 如果你使用了这样的应用,那么你应该设计一个计划来处理这种情况. 嵌入的 SQL 接口(ecpg)也受这个问题影响. 我们目前建议使用 ecpg 应用做接口的服务器 配置成发送英文信息.

维护信息翻译表需要许多志愿者的坚持不懈的努力, 他们就是希望 PostgreSQL 以它们的语言说话的人. 如果你的语言的信息目前还不可用或者没有完全翻译完成, 那么我们很欢迎你的协助.如果你想帮忙,那么请参考 开发人员手册或者向开发者邮递列表发邮件.