区域设置支持是指应用程序遵守有关字母表、排序、数字格式等的文化偏好。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 兼容”语义,大小写映射是“简单”变体。
icu
icu
提供程序使用外部 ICU 库。PostgreSQL 必须配置为支持 ICU。
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
是该设置的有效值。对于布尔设置,可以指定没有相应 -
value
的 -
key
,这意味着值为 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 章或写信给开发人员邮件列表。
如果您在文档中看到任何不正确、与您对特定功能的体验不符或需要进一步澄清的内容,请使用此表格报告文档问题。