地区设置支持是指应用程序尊重关于字母表、排序、数字格式等方面的文化偏好。PostgreSQL 使用标准 ISO C 和POSIX服务器操作系统提供的区域设置设施。有关详细信息,请参阅系统的文档。
使用 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字符集编码。
系统中有哪些区域设置名称取决于操作系统供应商所提供的内容和所安装的内容。在大多数 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
是这些类别。它们会影响索引的排序顺序,因此必须对其进行固定,否则文本列的索引将变得损坏。(但您可以使用整理规则来减轻此限制,正如在 第 23.2 节 中所讨论的那样。)这些类别的默认值是在运行 initdb
时确定的,并且这些值在创建新的数据库时使用,除非在 CREATE DATABASE
命令中另行指定。
其他语言环境类别可在任何时候通过设置与语言环境类别同名的服务器配置参数进行更改(有关详细信息,请参阅 第 19.11.2 节)。initdb
选择的值实际上只被写入配置文件 postgresql.conf
中,以便在服务器启动时用作默认值。如果您从 postgresql.conf
中删除这些赋值,那么服务器将从其执行环境继承设置。
请注意,服务器的语言环境行为是由服务器看到的环境变量确定的,而不是由任何客户端的环境确定的。因此,务必在启动服务器之前配置正确的语言环境设置。因此,如果客户端和服务器在不同的语言环境中设置,消息可能会以不同的语言显示,具体取决于它们的来源。
当我们谈到从执行环境中继承语言环境时,在大多数操作系统上,这意味着以下内容:对于给定的语言环境类别(例如整理规则),将按此顺序查询以下环境变量,直到找到一个被设置的变量为止: LC_ALL
、LC_COLLATE
(或与各个类别相对应的变量)、LANG
。如果这些环境变量均未设置,那么语言环境将默认为 C
。
一些消息本地化库还会查看环境变量 LANGUAGE
,它将覆盖所有其他语言环境设置,以便设置消息的语言。如有疑问,请参阅您操作系统的文档,特别是有关 gettext 的文档。
要启用消息被翻译成用户的首选语言,NLS必须在构建时选择(configure --enable-nls
)。所有其他语言环境支持都会自动内置。
语言环境设置会影响以下 SQL 功能
在 PostgreSQL 中使用 C
或 POSIX
以外的语言环境的缺点是会影响性能。它会减慢字符处理速度,并阻止在 LIKE
中使用普通索引。因为这个原因,仅在确实需要时才使用语言环境。
为了变通处理,允许 PostgreSQL 在非 C 语言环境下将索引与 LIKE
子句搭配使用,存在几个自定义运算符类。这些运算符允许创建执行严格逐字符比较的索引,忽略语言环境比较规则。请参阅 第 11.10 节 了解详情。另一种方法是在 C
校对中创建索引,如 第 23.2 节 所述。
根据要求可以在不同的作用域中选择语言环境。上述概述显示了如何使用 initdb
指定语言环境,以为整个集群设置默认值。下面列表显示了语言环境可以在哪里选择。每个项目都为后续项目提供默认值,每个较低项目都允许以更细的粒度覆盖默认值。
如上所述,操作系统环境为新初始化数据库集群的区域设置提供了默认值。在许多情况下,这就足够了:如果操作系统配置为期望的语言/地区,则 PostgreSQL 默认情况下也将根据该区域设置进行操作。
如上所示,initdb
的命令行选项指定了新初始化数据库集群的区域设置。如果操作系统没有数据库系统所需的区域设置配置,请使用该选项。
可以分别为每个数据库选择一个区域设置。SQL 命令 CREATE DATABASE
及其命令行等价项 createdb
设置了该选项。例如,如果一个数据库集群容纳具有不同需求的多个租户的数据库,可以使用此选项。
可以针对各个表列设置区域设置。这使用了一个名为 排序规则 的 SQL 对象,并在 第 23.2 节 中进行了说明。例如,可以使用该功能对不同语言中的数据进行排序或自定义特定表的排序顺序。
最后,可以为各个查询选择区域设置。这同样使用了 SQL 排序规则对象。该功能可用于根据运行时选项更改排序顺序,又或者用于临时试验。
区域设置提供商指定哪个库定义了排序规则和字符分类的区域设置行为。
上面所述用于选择区域设置的命令和工具,每个都有一个选择区域设置提供商的选项。以下是如何使用 ICU 提供商初始化数据库集群的一个示例
initdb --locale-provider=icu --icu-locale=en
有关详细信息,请查看各个命令和程序的描述。请注意,您可以在不同粒度上混合区域设置提供商,例如,对集群使用默认的 libc
,但其中一个数据库使用 icu
提供商,然后在这些数据库中使用任何提供程序的排序规则对象。
无论区域设置提供商如何,操作系统仍用于提供一些区域设置感知行为,例如消息(请参阅 lc_messages)。
可用区域设置提供商如下所列
builtin
builtin
提供商使用内置操作。此提供商仅支持 C
和 C.UTF-8
区域设置。
C
语言环境行为与 libc 提供程序中的 C
语言环境完全相同。在使用此语言环境时,该行为可能取决于数据库编码。
C.UTF-8
语言环境仅在数据库编码为 UTF-8
时才可用,并且该行为基于 Unicode。校对仅使用代码点值。正则表达式字符类别基于“POSIX Compatible”语义,大小写映射是“simple”变体。
icu
icu
提供程序使用外部 ICU 库。PostgreSQL
必须以支持方式进行配置。
ICU 提供的校对和字符分类行为与操作系统和数据库编码无关,如果您希望切换到其他平台且结果没有任何变化,那么这是首选。LC_COLLATE
和 LC_CTYPE
可独立于 ICU 语言环境进行设置。
对于 ICU 提供程序,结果可能取决于所用 ICU 库的版本,因为该库会更新以反映自然语言的随时间变化。
libc
libc
提供程序使用操作系统的 C 库。校对和字符分类行为由设置 LC_COLLATE
和 LC_CTYPE
控制,因此它们不能独立设置。
在使用 libc 提供程序时,相同的语言环境名称可能在不同平台上有不同的行为。
ICU 语言环境名称格式为 语言标记。
CREATE COLLATION mycollation1 (provider = icu, locale = 'ja-JP'); CREATE COLLATION mycollation2 (provider = icu, locale = 'fr');
在使用 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"
如果您看到此通知,请确保 provider
和 locale
是预期结果。使用 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
,否则仍然会创建排序规则,但行为可能与用户的预期不同。
由 BCP 47 中定义的语言标记是用于标识语言、地区以及与区域设置相关其他信息的一种标准化标识符。
基本语言标记仅仅是 language
-
region
;甚至只有 language
。 language
是语言代码(例如,fr
表示法语), region
是地区代码(例如,CA
表示加拿大)。示例:ja-JP
、de
或 fr-CA
。
排序规则设置可以包含在语言标记中,以自定义排序规则行为。ICU 允许大量自定义操作,例如对重音、大小写和标点的敏感性(或不敏感性);文本内数字的处理;以及许多其他选项,以满足各种用途的要求。
若要将此附加排序规则信息包含在语言标记中,请附加 -u
以指示存在附加排序规则设置,后跟一个或多个 -
key
-
value
对。 key
是 排序规则设置 的键, value
是该设置的有效值。对于布尔设置,可以指定 -
key
,而无需指定对应的 -
value
,这表示 true
的值。
例如,语言标记 en-US-u-kn-ks-level2
表示使用美国区域的英语语言的语言环境,排序规则设置 kn
设置为 true
,而 ks
设置为 level2
。这些设置表示排序规则将不区分大小写并将一系列数字视为单个数字
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)
有关详细信息和自定义整理信息与语言标记结合用于区域设置的其它示例,请参阅 第 23.2.3 节。
如果区域设置支持未按上述说明正常工作,请检查您操作系统中的区域设置支持是否正确配置。要检查系统上安装了哪些区域设置,如果操作系统提供了 locale -a
命令,您可以使用该命令。
检查 PostgreSQL 是否实际上正在使用您认为它使用的区域设置。当创建一个数据库时,会确定 LC_COLLATE
和 LC_CTYPE
设置,并且除了创建新数据库之外,不能更改这些设置。包括 LC_MESSAGES
和 LC_MONETARY
在内的其它区域设置初始由服务器启动的环境决定,但可在运行过程中更改。您可以使用 SHOW
命令检查活动区域设置。
源发行中的 src/test/locale
目录包含 PostgreSQL 区域设置支持的测试套件。
通过解析错误消息文本来处理服务器端错误的客户端应用程序,显然当服务器的消息以其他语言发送时,会出现问题。建议此类应用程序的作者改为使用错误代码方案。
维护消息翻译目录,需要希望了解 PostgreSQL 说他们的首选语言时情况良好的许多志愿者的持续努力。如果当前没有提供或未完全翻译您语言的消息,我们将感激您的帮助。如果您想提供帮助,请参阅 第 55 章 或写信到开发者邮件列表。