22.1. 区域支持

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

22.1.1. 概述

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

initdb --locale=sv_SE

Unix系统下的这个例子就把区域设置为说瑞典语(sv),并且在瑞典地区(SE)。 其它的可能性是en_US(美国英语)和fr_CA(加拿大法语)等等。 如果有多于一种的字符集可以用于同一个区域,那么声明看起来会像_language_territory.codeset_。 比如,fr_BE.UTF-8表示为在比利时(BE)地区使用的法语(fr),并且使用UTF-8字符集编码。

你的系统里有哪些可用的区域设置,它们的名字是什么, 这些信息都取决于你的操作系统提供商提供了什么以及你安装了什么东西。 在大多数系统上,命令locale -a将提供所有可用区域的一个列表。 Windows使用更详细的区域名称,比如German_Germany或者Swedish_Sweden.1252, 但是原则是一样的。

有时候,把几种区域规则混合起来也很有用,比如, 使用英语排序规则而用西班牙语消息。为了支持这些, 我们有一套区域子范畴用于控制区域规则的某一方面:

LC_COLLATE 字符串排序顺序
LC_CTYPE 字符分类(什么是字母?是否区分大小写?)
LC_MESSAGES 消息的语言
LC_MONETARY 货币金额的格式
LC_NUMERIC 数值格式
LC_TIME 日期和时间格式

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

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

一些区域范畴的值必须在创建数据库时固定下来。 您可以对不同的数据库使用不同的设置,但一旦创建一个数据库,你就再也不能更改它们了。 LC_COLLATELC_CTYPE就是这样的范畴。 它们影响索引的排序顺序,因此它们必需保持固定,否则在文本字段上的索引将会崩溃。 (但是你可以使用排序规则(collation)缓解这种限制,正如Section 22.2中讨论的)。 当运行initdb时确定这些范畴的缺省值, 这些值被用于创建新的数据库,除非在CREATE DATABASE命令中明确指定。

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

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

Note: 在我们谈到从执行环境继承区域的时候, 我们的意思是在大多数操作系统上的下列动作: 对于一个给定的区域范畴, 比如排序规则,按照下面的顺序评估这些环境变量, 直到找到一个已设置的:LC_ALL, LC_COLLATE (或者对应于相应范畴的其他变量), LANG。 如果这些环境变量一个都没有设置,那么区域缺省为C

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

要能够将消息翻译成用户选择的语言,编译时必需选择NLS选项(configure --enable-nls)。 其它区域支持是自动包含的。

22.1.2. 行为

区域设置特别影响下面的 SQL 特性:

  • 查询中使用ORDER BY或者对文本数据的标准比较操作符进行排序

  • upper, lowerinitcap函数

  • 模式匹配运算符(LIKE, SIMILAR TO, 以及POSIX-风格的正则表达式); 区域影响大小写不敏感的匹配和通过字符分类正则表达式的字符分类。

  • to_char函数族

  • 使用LIKE子句的索引能力

PostgreSQL里使用非C或者POSIX区域的缺点是性能影响。 它降低了字符处理的速度并阻止了在LIKE类查询里面普通索引的使用。 因此,应该只有在你实际上需要的时候才使用它。

为了允许PostgreSQL在非C区域下的LIKE子句中使用索引, 有好几个自定义的操作符类可以用。 这些操作符类允许创建一个严格地比较每个字符的索引, 而忽略区域比较规则。请参考Section 11.9获取更多信息。 另外一个方法是使用C collation创建索引,正如Section 22.2 中讨论的。

22.1.3. 问题

如果经过上面解释后区域支持仍然不能运转, 那你就要检查一下操作系统的区域支持是否正确配置。 要检查某个区域是否安装并且正常运转, 你可以使用locale -a命令(如果你的系统提供了该命令)。

请检查核实PostgreSQL确实使用了你认为它该用的区域设置。 LC_COLLATELC_CTYPE的设置都是在数据库创建时决定的, 不能被改变除非创建新的数据库。其它的区域设置包括 LC_MESSAGESLC_MONETARY都是由服务器的启动环境决定的, 但是可以在运行时修改。你可以用SHOW命令检查数据库正在使用的区域设置。

源码发布中的src/test/locale目录包含 PostgreSQL的区域支持测试套件。

那些通过解析错误消息文本处理服务器端错误的客户端应用很明显会有问题, 因为服务器信息可能会以不同的语言表示。我们建议这类应用的开发人员改用错误代码机制。

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