2025年9月25日: PostgreSQL 18 发布!
支持的版本: 当前 (18) / 17 / 16 / 15 / 14 / 13
开发版本: 开发版
不支持的版本: 12 / 11 / 10 / 9.6 / 9.5 / 9.4 / 9.3 / 9.2 / 9.1 / 9.0 / 8.4 / 8.3 / 8.2

23.1. 区域设置支持 #

区域设置支持是指应用程序遵循关于字母表、排序、数字格式等方面的文化偏好。PostgreSQL 使用标准的 ISO C 和POSIX服务器操作系统提供的区域设置功能。有关更多信息,请参阅您系统的文档。

23.1.1. 概述 #

区域设置支持在创建数据库集群时使用 initdb 自动初始化。默认情况下,initdb 将使用其执行环境的区域设置来初始化数据库集群,因此,如果您的系统已设置为使用您想要的数据库集群区域设置,则无需执行其他操作。如果您想使用不同的区域设置(或不确定您的系统设置了哪个区域设置),则可以通过指定 --locale 选项来明确指示 initdb 使用哪个区域设置。例如:

initdb --locale=sv_SE

此 Unix 系统示例将区域设置设置为瑞典语(sv),在瑞典(SE)使用。其他可能的设置包括 en_US(美式英语)和 fr_CA(加拿大法语)。如果一个区域设置可以使用多种字符集,则规范可以采用 语言_地区.字符集 的形式。例如,fr_BE.UTF-8 代表在比利时(BE)使用的法语(fr),使用UTF-8字符集编码。

您的系统上可用的区域设置及其名称取决于操作系统供应商提供的以及安装的内容。在大多数 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 是这些类别。它们影响索引的排序顺序,因此必须保持固定,否则文本列上的索引会损坏。(但您可以使用排序规则来减轻此限制,如 第 23.2 节中所述。)这些类别的默认值在运行 initdb 时确定,并且新数据库创建时将使用这些值,除非在 CREATE DATABASE 命令中另有指定。

其他区域设置类别可以随时更改,方法是设置与区域设置类别同名的服务器配置参数(有关详细信息,请参阅 第 19.11.2 节)。initdb 选择的值实际上只写入 postgresql.conf 配置文件中,作为服务器启动时的默认值。如果从 postgresql.conf 中删除这些赋值,服务器将继承其执行环境的设置。

请注意,服务器的区域设置行为由服务器看到的 arement 变量决定,而不是由任何客户端的 arement 决定。因此,请务必在启动服务器之前配置正确的区域设置。其后果是,如果客户端和服务器在不同的区域设置中设置,消息可能会显示为不同的语言,具体取决于其来源。

注意

当我们谈论从执行环境继承区域设置时,在大多数操作系统上意味着:对于给定的区域设置类别,例如排序,将按照以下顺序检查 arement 变量,直到找到一个已设置的变量为止:LC_ALLLC_COLLATE(或对应于相应类别的变量)、LANG。如果这些 arement 变量均未设置,则区域设置默认为 C

某些消息本地化库还检查 LANGUAGE arement 变量,该变量会覆盖所有其他区域设置,用于设置消息的语言。如有疑问,请参考您的操作系统文档,特别是关于 gettext 的文档。

要使消息能够翻译成用户偏好的语言,NLS必须在构建时选择(configure --enable-nls)。所有其他区域设置支持都是自动内置的。

23.1.2. 行为 #

区域设置会影响以下 SQL 功能:

  • 使用 ORDER BY 或文本数据的标准比较运算符的查询中的排序顺序

  • upperlowerinitcap 函数

  • 模式匹配运算符(LIKESIMILAR TO 和 POSIX 风格的正则表达式);区域设置会影响不区分大小写的匹配以及字符类正则表达式的字符分类

  • to_char 系列函数

  • 使用 LIKE 子句的索引的能力

PostgreSQL 中使用非 CPOSIX 区域设置的缺点是其性能影响。它会减慢字符处理速度,并阻止普通索引被 LIKE 使用。因此,仅在您确实需要时才使用区域设置。

作为一种变通方法,允许 PostgreSQL 在非 C 区域设置下使用带 LIKE 子句的索引,存在几种自定义操作符类。这些允许创建执行严格逐字符比较的索引,忽略区域设置比较规则。有关更多信息,请参阅 第 11.10 节。另一种方法是创建使用 C 排序规则的索引,如 第 23.2 节中所述。

23.1.3. 选择区域设置 #

根据需求,可以在不同的作用域中选择区域设置。以上概述展示了如何使用 initdb 指定区域设置来设置整个集群的默认值。以下列表显示了可以在何处选择区域设置。每个项目为后续项目提供默认值,每个较低的项目允许在更精细的粒度上覆盖默认值。

  1. 如上所述,操作系统环境为新初始化数据库集群的区域设置提供了默认值。在许多情况下,这就足够了:如果操作系统已配置为所需的语言/地区,则默认情况下 PostgreSQL 也会根据该区域设置运行。

  2. 如上所示,initdb 的命令行选项为新初始化的数据库集群指定区域设置。如果操作系统没有您想要的数据库系统的区域设置配置,则使用此选项。

  3. 可以为每个数据库单独选择区域设置。SQL 命令 CREATE DATABASE 及其命令行等效命令 createdb 具有相应的选项。例如,如果一个数据库集群包含多个具有不同需求的租户的数据库,则可以使用此选项。

  4. 可以为单个表列设置区域设置。这使用一个称为排序规则的 SQL 对象,并在 第 23.2 节中进行了说明。例如,使用此选项可以以不同语言对数据进行排序,或自定义特定表的排序顺序。

  5. 最后,可以为单个查询选择区域设置。同样,这使用 SQL 排序规则对象。这可以用于根据运行时选择更改排序顺序,或用于临时实验。

23.1.4. 区域设置提供程序 #

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

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

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

有关详细信息,请参阅相应命令和程序的说明。请注意,您可以在不同粒度上混合使用区域设置提供程序,例如,为集群默认使用 libc,但有一个数据库使用 icu 提供程序,然后在这些数据库中使用任一提供程序的排序规则对象。

无论使用哪种区域设置提供程序,操作系统仍用于提供某些区域设置感知行为,例如消息(请参阅 lc_messages)。

下面列出了可用的区域设置提供程序:

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 区域设置进行设置。

注意

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

libc

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

注意

在使用 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 中定义)是用于标识语言、地区和其他关于区域设置信息的标准化标识符。

基本语言标签只是 语言-地区;甚至可以只包含 语言语言 是语言代码(例如,法语是 fr),地区 是地区代码(例如,加拿大是 CA)。示例:ja-JPdefr-CA

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

要在语言标签中包含此附加的排序信息,请附加 -u,它表示存在附加的排序设置,后跟一个或多个 -- 对。排序设置的键, 是该设置的有效值。对于布尔设置,可以省略 -,只指定 -,表示值为 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)

有关详细信息和使用具有自定义排序信息的语言标签的附加示例,请参阅 第 23.2.3 节

23.1.6. 问题 #

如果区域设置支持不起作用,请检查操作系统中的区域设置支持是否已正确配置。要检查您的系统上安装了哪些区域设置,您可以使用 locale -a 命令,如果您的操作系统提供了该命令。

检查 PostgreSQL 是否实际使用了您认为它应该使用的区域设置。LC_COLLATELC_CTYPE 设置在创建数据库时确定,除非创建新数据库,否则无法更改。其他区域设置包括 LC_MESSAGESLC_MONETARY,它们最初由服务器启动时的环境决定,但可以动态更改。您可以使用 SHOW 命令检查活动的区域设置。

源代码发行版中的 src/test/locale 目录包含一个用于 PostgreSQL 区域设置支持的测试套件。

通过解析错误消息文本来处理服务器端错误的客户端应用程序,在服务器消息语言不同时显然会遇到问题。此类应用程序的作者应改用错误代码方案。

维护消息翻译目录需要大量志愿者持续的努力,他们希望看到 PostgreSQL 能够很好地支持他们喜欢的语言。如果您的语言的消息当前不可用或未完全翻译,我们将非常感谢您的协助。如果您想帮忙,请参阅 第 56 章或写信给开发人员邮件列表。

提交更正

如果您在文档中看到任何不正确、与您对特定功能的体验不符或需要进一步澄清的内容,请使用此表格报告文档问题。