24.1. 语言环境支持#
语言环境支持是指应用程序尊重有关字母表、排序、数字格式等的文化偏好。PostgreSQL使用服务器操作系统提供的标准 ISO C 和POSIX语言环境设施。有关其他信息,请参阅系统的文档。
24.1.1. 概述#
使用initdb
创建数据库集群时,会自动初始化区域设置支持。默认情况下,initdb
会使用其执行环境的区域设置来初始化数据库集群,因此,如果您的系统已经设置为使用您希望在数据库集群中使用的区域设置,则无需执行任何其他操作。如果您想使用不同的区域设置(或者不确定系统设置为哪个区域设置),则可以通过指定--locale
选项来指示initdb
确切使用哪个区域设置。例如
initdb --locale=sv_SE
此 Unix 系统示例将区域设置设置为瑞典语(sv
),在瑞典使用(SE
)。其他可能性可能包括en_US
(美国英语)和fr_CA
(加拿大法语)。如果一个区域设置可以使用多个字符集,则规范可以采用*language_territory.codeset
*形式。例如,fr_BE.UTF-8
表示使用UTF-8字符集编码的比利时(BE)法语(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. ICU 区域设置#
24.1.5.1. ICU 区域设置名称#
区域设置名称的 ICU 格式是语言标记。
CREATE COLLATION mycollation1 (provider = icu, locale = 'ja-JP');
CREATE COLLATION mycollation2 (provider = icu, locale = 'fr');
24.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"
如果看到此通知,请确保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
,否则仍将创建排序,但行为可能与用户预期不同。
24.1.5.3. 语言标记#
在 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)
有关详细信息和使用带有语言环境自定义校对信息的语言标记的其他示例,请参见第 24.2.3 节。
24.1.6. 问题#
如果语言环境支持未按上述说明工作,请检查操作系统中的语言环境支持是否配置正确。要检查系统中安装了哪些语言环境,如果操作系统提供了该命令,可以使用命令locale -a
。
检查PostgreSQL是否实际使用您认为它使用的语言环境。在创建数据库时确定LC_COLLATE
和LC_CTYPE
设置,并且只能通过创建新数据库来更改这些设置。包括LC_MESSAGES
和LC_MONETARY
在内的其他语言环境设置最初由服务器启动的环境确定,但可以在运行中更改。可以使用SHOW
命令检查活动语言环境设置。
源发行版中的目录src/test/locale
包含PostgreSQL语言环境支持的测试套件。
通过解析错误消息文本来处理服务器端错误的客户端应用程序在服务器消息使用不同语言时显然会出现问题。建议此类应用程序的作者使用错误代码方案。
维护消息翻译目录需要许多志愿者的持续努力,他们希望看到PostgreSQL很好地使用他们首选的语言。如果目前没有提供您语言的消息或没有完全翻译,我们将非常感谢您的帮助。如果您想提供帮助,请参阅第 57 章或写信给开发人员邮件列表。