受支持版本: 当前版本 (18) / 17 / 16 / 15 / 14
开发版本: devel

Chapter 23. 本地化

本章从管理员的角度介绍可用的本地化特性。 PostgreSQL支持两类本地化机制:

  • 利用操作系统的区域设置(locale)特性,提供与区域设置相关的排序顺序、 数字格式、翻译后的消息以及其他方面的支持。详见Section 23.1Section 23.2

  • 提供多种字符集,以支持存储各种语言的文本,并提供客户端与服务器之间的 字符集转换。详见Section 23.3

23.1. 区域设置支持 #

区域设置支持是指应用程序在字母表、排序、数字格式等 方面尊重文化偏好。PostgreSQL使用服务器操作系统 提供的标准 ISO C 和POSIX区域设置机制。更多信息请参考 系统文档。

23.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_GermanySwedish_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_COLLATELC_CTYPE就属于这类 类别。它们会影响索引的排序顺序,因此必须保持固定,否则文本列上的索引会 损坏。(不过,可以通过排序规则缓解这一限制,参见Section 23.2。)这些类别的默认值在运行initdb 时确定,创建新数据库时会使用这些值,除非在CREATE DATABASE 命令中另行指定。

其他区域设置类别可以在任何时候通过设置与其同名的服务器配置参数来更改 (详见Section 19.6.2)。initdb 选择的值实际上只是写入配置文件postgresql.conf中, 作为服务器启动时的默认值。如果从postgresql.conf中 删除这些赋值,服务器就会从其执行环境继承相应设置。

请注意,服务器的区域设置行为由服务器看到的环境变量决定,而不是由任何客 户端的环境决定。因此,务必在启动服务器前配置好正确的区域设置。由此带来 的一个结果是,如果客户端和服务器使用不同的区域设置,消息可能会因其来源 不同而显示为不同语言。

Note

这里所说的从执行环境继承区域设置,在大多数操作系统上是指:对于某个给 定的区域设置类别,例如排序规则,会按以下顺序检查环境变量,直到找到一个 已设置的变量为止:LC_ALLLC_COLLATE(或相应类别对应的变量)、LANG。 如果这些环境变量都没有设置,则区域设置默认为C

某些消息本地化库还会查看环境变量LANGUAGE,它会覆盖所有 其他用于设置消息语言的区域设置。如果有疑问,请参考操作系统文档,尤其是 关于gettext的文档。

若要让消息可以翻译为用户偏好的语言,构建时必须启用NLSconfigure --enable-nls)。所有其他区域设置支持都会 自动内置。

23.1.2. 行为 #

区域设置会影响下列 SQL 特性:

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

  • upperlowerinitcap函数

  • 模式匹配操作符(LIKESIMILAR TO 以及 POSIX 风格正则表达式);区域设置既会影响大小写不敏感匹配,也会 影响字符类正则表达式中的字符分类

  • to_char函数族

  • LIKE子句使用索引的能力

PostgreSQL中使用CPOSIX之外的区域设置,缺点是会影响性能。它会减慢字 符处理速度,并阻止普通索引用于LIKE。因此,只有在确 有需要时才应使用区域设置。

为了让PostgreSQL在非 C 区域设置下也能对 LIKE子句使用索引,存在若干自定义操作符类可供使用。 它们允许创建执行严格逐字符比较、忽略区域设置比较规则的索引。详见Section 11.10。另一种方法是创建使用C 排序规则的索引,如Section 23.2所述。

23.1.3. 选择区域设置 #

区域设置可以根据需要在不同范围内进行选择。上面的概述展示了如何使用 initdb为整个集簇设置默认值。下面的列表给出了可以选 择区域设置的位置。每一项都会为后续项提供默认值,而越靠后的项允许以更细 粒度覆盖这些默认值。

  1. 如上所述,操作系统环境会为新初始化的数据库集簇提供区域设置默认值。在 很多情况下,这已经足够:如果操作系统配置为所需的语言/地区,那么 PostgreSQL默认也会遵循该区域设置的行为。

  2. 如上所示,initdb的命令行选项可为新初始化的数据库 集簇指定区域设置。如果操作系统没有提供数据库系统所需的区域设置配置, 就应使用这种方式。

  3. 每个数据库都可以单独选择区域设置。SQL 命令CREATE DATABASE 及其命令行等效程序createdb都提供了相应选项。例 如,如果一个数据库集簇中承载了多个租户的数据库,而这些租户有不同的需 求,就可以使用这种方式。

  4. 区域设置还可以针对单个表列设置。这使用一个名为排序规则 的 SQL 对象,详见Section 23.2。例如,可用它对不同语 言的数据进行排序,或自定义某个特定表的排序顺序。

  5. 最后,还可以为单个查询选择区域设置。同样,这也是通过 SQL 排序规则对象 实现的。它可以用于根据运行时选择改变排序顺序,或进行临时实验。

23.1.4. 区域设置提供程序 #

区域设置提供程序指定由哪个库来定义排序规则和字符分类的区域设置行为。

如上所述,用于选择区域设置的命令和工具都提供了选择区域设置提供程序的选 项。下面是一个使用 ICU 提供程序初始化数据库集簇的示例:

initdb --locale-provider=icu --icu-locale=en

有关详细信息,请参阅相应命令和程序的说明。请注意,你可以在不同粒度上混 合使用区域设置提供程序,例如集簇默认使用libc,但其 中某个数据库使用icu提供程序,而该数据库内部的排序规 则对象又可以使用任一提供程序。

无论使用哪种区域设置提供程序,操作系统仍会用于提供某些区域设置相关的行 为,例如消息(参见lc_messages)。

可用的区域设置提供程序如下:

builtin

builtin提供程序使用内置操作。此提供程序仅支持 CC.UTF-8PG_UNICODE_FAST区域设置。

C区域设置的行为与 libc 提供程序中的 C区域设置相同。使用该区域设置时,其行为可能取决于 数据库编码。

C.UTF-8区域设置仅在数据库编码为 UTF-8时可用,并且其行为基于 Unicode。排序规则仅使 用代码点值。正则表达式字符类基于“POSIX 兼容”语义,大小写映射使用 “简单”变体。

PG_UNICODE_FAST区域设置仅在数据库编码为 UTF-8时可用,并且其行为基于 Unicode。排序规则仅使 用代码点值。正则表达式字符类基于“标准”语义,大小写映射使用“完整” 变体。

icu

icu提供程序使用外部 ICU库。 PostgreSQL必须在构建时配置了 ICU 支持。

ICU 提供与操作系统和数据库编码无关的排序与字符分类行为。如果你希望将 来迁移到其他平台而不改变结果,这通常更可取。LC_COLLATELC_CTYPE可以独立于 ICU 区域设置进行设置。

Note

对于 ICU 提供程序,结果可能取决于所使用的 ICU 库版本,因为该库会随 时间推移更新,以反映自然语言的变化。

libc

libc提供程序使用操作系统的 C 库。排序与字符分类行 为由LC_COLLATELC_CTYPE设置控 制,因此它们不能独立设置。

Note

使用 libc 提供程序时,同一个区域设置名称在不同平台上可能表现不同。

23.1.5. ICU 区域设置 #

23.1.5.1. ICU 区域设置名称 #

ICU 格式的区域设置名称采用语言标签

CREATE COLLATION mycollation1 (provider = icu, locale = 'ja-JP');
CREATE COLLATION mycollation2 (provider = icu, locale = 'fr');

23.1.5.2. 区域设置规范化和验证 #

在定义新的 ICU 排序规则对象,或者定义以 ICU 为提供程序的数据库时,给 定的区域设置名称如果还不是语言标签形式,就会被转换(“规范化”)成语言 标签。例如:

CREATE COLLATION mycollation3 (provider = icu, locale = 'en-US-u-kn-true');
NOTICE:  using standard form "en-US-u-kn" for locale "en-US-u-kn-true"
CREATE COLLATION mycollation4 (provider = icu, locale = 'de_DE.utf8');
NOTICE:  using standard form "de-DE" for locale "de_DE.utf8"

如果看到这类通知,请确认providerlocale 是否符合预期。为了在使用 ICU 提供程序时获得一致结果,应直接指定规范化 的语言标签,而不要依赖这种转换。

没有语言名称的区域设置,或特殊语言名root,会被转换 成语言und(“未定义”)。

ICU 可以将大多数 libc 区域设置名称以及一些其他格式转换为语言标签,这有 助于更容易地迁移到 ICU。如果在 ICU 中使用 libc 风格的区域设置名称,其 行为可能与 libc 中并不完全一致。

如果在解释区域设置名称时出现问题,或者该区域设置名称表示 ICU 无法识别 的语言或地区,你会看到如下警告:

CREATE COLLATION nonsense (provider = icu, locale = 'nonsense');
WARNING:  ICU locale "nonsense" has unknown language "nonsense"
HINT:  To disable ICU locale validation, set parameter icu_validation_level to DISABLED.
CREATE COLLATION

icu_validation_level控制消息的报告方式。除非将其设为 ERROR,否则排序规则仍会被创建,但其行为可能不是用户 所期望的。

23.1.5.3. 语言标签 #

语言标签在 BCP 47 中定义,是一种用于标识语言、地区以及其他区域设置信息 的标准化标识符。

基本语言标签就是 language-region; 甚至也可以只有languagelanguage是语言代码(例如法语为 fr),region是地区代码 (例如加拿大为CA)。例如:ja-JPdefr-CA

语言标签中还可以包含排序设置,以自定义排序行为。ICU 允许非常广泛的定 制,例如对重音、大小写和标点的敏感性(或不敏感性)、文本中数字的处理 方式,以及许多其他选项,以满足不同用途。

若要在语言标签中包含这些附加排序信息,请附加-u,表 示存在附加排序设置,后跟一个或多个 -key-value 对。key排序设置的键, value则是该设置的有效值。对于布尔设置,可以 只写-key而省略对应的 -value,这意味着其值为 true

例如,语言标签en-US-u-kn-ks-level2表示美国区域的英 语区域设置,其中排序设置kntruekslevel2。这些设置意味着该排 序规则不区分大小写,并把一串数字视为一个整体数字:

CREATE COLLATION mycollation5 (provider = icu, deterministic = false, locale = 'en-US-u-kn-ks-level2');
SELECT 'aB' = 'Ab' COLLATE mycollation5 as result;
 result
--------
 t
(1 row)

SELECT 'N-45' < 'N-123' COLLATE mycollation5 as result;
 result
--------
 t
(1 row)

有关详细信息以及在区域设置中使用带自定义排序信息的语言标签的更多示 例,请参见Section 23.2.3

23.1.6. 问题 #

如果区域设置支持没有像上面说明的那样工作,请检查操作系统中的区域设置支 持是否已经正确配置。要检查系统中安装了哪些区域设置,可以使用 locale -a命令(如果操作系统提供该命令)。

请确认PostgreSQL实际使用的区域设置就是你预 期的区域设置。LC_COLLATELC_CTYPE是在创 建数据库时确定的,除非重新创建数据库,否则不能更改。其他区域设置,包括 LC_MESSAGESLC_MONETARY,最初由启动服 务器时的环境决定,但可以在运行中动态修改。你可以使用SHOW 命令检查当前生效的区域设置。

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

那些通过解析错误消息文本来处理服务器端错误的客户端应用,显然会遇到问 题,因为服务器消息可能使用不同语言。这类应用的作者应改用错误代码机制。

维护消息翻译目录需要许多志愿者持续投入,他们希望 PostgreSQL能够良好地支持他们偏好的语言。如 果你所用语言的消息目前还不可用,或尚未完全翻译,我们将非常感谢你的协 助。如果你愿意帮忙,请参考Chapter 55,或向开发者邮件列表写 信。

提交更正

如果您发现文档中有不正确的内容、与您使用特定功能的经验不符或需要进一步说明,请使用此表单来报告文档问题。