第 24 章 本地化
目录
本章从管理员的角度介绍可用的本地化特性。PostgreSQL 支持两类本地化机制:
24.1. 区域设置支持 #
区域设置支持是指应用程序在字母表、排序、数字格式等方面尊重文化偏好。PostgreSQL 使用服务器操作系统提供的标准 ISO C 和 POSIX 区域设置机制。更多信息请参考系统文档。
24.1.1. 概述 #
在使用 initdb 创建数据库集簇时,区域设置支持会自动初始化。默认情况下,initdb 会使用其执行环境中的区域设置来初始化数据库集簇,因此如果你的系统已经设置为数据库集簇想要使用的区域设置,就无需额外操作。如果想使用不同的区域设置(或者不确定系统当前设置了哪种区域设置),可以通过指定 --locale 选项,精确告诉 initdb 使用哪种区域设置。例如:
initdb --locale=sv_SE
这个 Unix 系统上的示例把区域设置为在瑞典(SE)使用的瑞典语(sv)。其他可能的值包括 en_US(美国英语)和 fr_CA(加拿大法语)。如果一个区域设置可以使用多于一种字符集,则说明可以采用
language_territory.codeset 这样的形式。例如,fr_BE.UTF-8 表示在比利时(BE)使用、采用
UTF-8 字符集编码的法语(fr)。
系统上有哪些区域设置可用,以及它们以什么名称出现,取决于操作系统供应商提供了什么以及实际安装了什么。在大多数 Unix 系统上,命令
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。
如果希望系统表现得像没有区域设置支持一样,可使用特殊区域设置名
C,或等效的 POSIX。
某些区域设置类别的值必须在创建数据库时固定下来。你可以为不同数据库使用不同设置,但数据库一旦创建,这些类别的值就不能再更改。LC_COLLATE 和 LC_CTYPE 就属于这类类别。它们会影响索引的排序顺序,因此必须保持固定,否则文本列上的索引会损坏。(不过,可以通过排序规则缓解这一限制,参见第 24.2 节。)这些类别的默认值在运行 initdb
时确定,创建新数据库时会使用这些值,除非在 CREATE DATABASE
命令中另行指定。
其他区域设置类别可以在任何时候通过设置与其同名的服务器配置参数来更改(详见第 20.11.2 节)。initdb
选择的值实际上只是写入配置文件 postgresql.conf 中,作为服务器启动时的默认值。如果从 postgresql.conf 中删除这些赋值,服务器就会从其执行环境继承相应设置。
请注意,服务器的区域设置行为由服务器看到的环境变量决定,而不是由任何客户端的环境决定。因此,务必在启动服务器前配置好正确的区域设置。由此带来的一个结果是,如果客户端和服务器使用不同的区域设置,消息可能会因其来源不同而显示为不同语言。
注意
这里所说的从执行环境继承区域设置,在大多数操作系统上是指:对于某个给定的区域设置类别,例如排序规则,会按以下顺序检查环境变量,直到找到一个已设置的变量为止:LC_ALL、LC_COLLATE(或相应类别对应的变量)、LANG。如果这些环境变量都没有设置,则区域设置默认为 C。
某些消息本地化库还会查看环境变量 LANGUAGE,它会覆盖所有其他用于设置消息语言的区域设置。如果有疑问,请参考操作系统文档,尤其是关于 gettext 的文档。
若要让消息可以翻译为用户偏好的语言,构建时必须启用 NLS(configure --enable-nls)。所有其他区域设置支持都会自动内置。
24.1.2. 行为 #
区域设置会影响下列 SQL 特性:
在 PostgreSQL 中使用 C 或
POSIX 之外的区域设置,缺点是会影响性能。它会减慢字符处理速度,并阻止普通索引用于 LIKE。因此,只有在确有需要时才应使用区域设置。
为了让 PostgreSQL 在非 C 区域设置下也能对
LIKE 子句使用索引,存在若干自定义操作符类可供使用。它们允许创建执行严格逐字符比较、忽略区域设置比较规则的索引。详见第 11.10 节。另一种方法是创建使用 C
排序规则的索引,如第 24.2 节所述。
24.1.3. 选择区域设置 #
区域设置可以根据需要在不同范围内进行选择。上面的概述展示了如何使用
initdb 为整个集簇设置默认值。下面的列表给出了可以选择区域设置的位置。每一项都会为后续项提供默认值,而越靠后的项允许以更细粒度覆盖这些默认值。
如上所述,操作系统环境会为新初始化的数据库集簇提供区域设置默认值。在很多情况下,这已经足够:如果操作系统配置为所需的语言/地区,那么 PostgreSQL 默认也会遵循该区域设置的行为。
如上所示,
initdb的命令行选项可为新初始化的数据库集簇指定区域设置。如果操作系统没有提供数据库系统所需的区域设置配置,就应使用这种方式。每个数据库都可以单独选择区域设置。SQL 命令
CREATE DATABASE及其命令行等效程序createdb都提供了相应选项。例如,如果一个数据库集簇中承载了多个租户的数据库,而这些租户有不同的需求,就可以使用这种方式。区域设置还可以针对单个表列设置。这使用一个名为排序规则的 SQL 对象,详见第 24.2 节。例如,可用它对不同语言的数据进行排序,或自定义某个特定表的排序顺序。
最后,还可以为单个查询选择区域设置。同样,这也是通过 SQL 排序规则对象实现的。它可以用于根据运行时选择改变排序顺序,或进行临时实验。
24.1.4. 区域设置提供程序 #
PostgreSQL 支持多种区域设置提供程序,用于指定由哪个库提供区域设置数据。一种标准提供程序名是 libc,它使用操作系统 C 库提供的区域设置;操作系统提供的大多数工具也使用这些区域设置。另一种提供程序是 icu,它使用外部
ICU 库。只有在构建 PostgreSQL 时配置了 ICU 支持,才能使用 ICU 区域设置。
如上所述,用于选择区域设置的命令和工具都提供了选择区域设置提供程序的选项。前面的示例都使用默认的 libc 提供程序。下面是一个使用 ICU
提供程序初始化数据库集簇的示例:
initdb --locale-provider=icu --icu-locale=en
有关详细信息,请参阅相应命令和程序的说明。请注意,你可以在不同粒度上混合使用区域设置提供程序,例如集簇默认使用 libc,但其中某个数据库使用 icu 提供程序,而该数据库内部的排序规则对象又可以使用任一提供程序。
选择哪种区域设置提供程序取决于具体需求。对于大多数基本用途,两种提供程序都能给出足够好的结果。libc 提供程序的表现取决于操作系统提供的支持;不同操作系统的支持程度有所不同。对于高级用途,ICU 提供了更多区域设置变体和定制选项。
24.1.5. 问题 #
如果区域设置支持没有像上面说明的那样工作,请检查操作系统中的区域设置支持是否已经正确配置。要检查系统中安装了哪些区域设置,可以使用
locale -a 命令(如果操作系统提供该命令)。
请确认 PostgreSQL 实际使用的区域设置就是你预期的区域设置。LC_COLLATE 和 LC_CTYPE 是在创建数据库时确定的,除非重新创建数据库,否则不能更改。其他区域设置,包括
LC_MESSAGES 和 LC_MONETARY,最初由启动服务器时的环境决定,但可以在运行中动态修改。你可以使用 SHOW
命令检查当前生效的区域设置。
源码发布包中的 src/test/locale 目录包含
PostgreSQL 区域设置支持的测试套件。
那些通过解析错误消息文本来处理服务器端错误的客户端应用,显然会遇到问题,因为服务器消息可能使用不同语言。这类应用的作者应改用错误代码机制。
维护消息翻译目录需要许多志愿者持续投入,他们希望 PostgreSQL 能够良好地支持他们偏好的语言。如果你所用语言的消息目前还不可用,或尚未完全翻译,我们将非常感谢你的协助。如果你愿意帮忙,请参考第 57 章,或向开发者邮件列表写信。
报告文档问题
阅读 上游文档. 通过 PostgreSQL 文档反馈表单.