如何为国际数据库选择排序规则?


22

我正在设计一个数据库,该数据库将以不同的语言存储数据(使用UTF-8),所以我认为显示查询结果的最佳方法是在查询过程中根据用户的语言对其进行排序(因为不止一种正确的方法),如下所示:

SELECT a < b COLLATE "de_DE" FROM test1;

假设这是处理国际数据的正确方法,这是数据库本身的最佳整理方法?PostgreSQL文档说

C和POSIX归类均指定“传统C”行为,其中仅将ASCII字母“ A”至“ Z”视为字母,并且严格按字符代码字节值进行排序。

我认为这是这种情况下的最佳选择,还是我错了?

(奖金问题:在查询本身中选择排序规则是否太慢?)。


2
您将遭受的最大痛苦是,在多语言数据库中,您需要大量索引,因为可整理文本上的索引是特定于排序规则的。但是,如果您倾向于只在特定的排序规则/语言中进行搜索,则可以使用部分索引来帮助控制索引的大小。
Craig Ringer 2013年

2
引用来源时,添加链接。
Erwin Brandstetter

Answers:


27

C整理是正确的选择。

没有语言环境,一切都会更快。而且由于没有正确的排序规则,因此请创建没有排序规则的数据库,即使用C

必须为许多操作提供排序规则可能很痛苦。但是,默认排序规则和临时排序规则之间的速度不应有明显的差异。毕竟,它们只是未排序的数据,排序时会应用排序规则。

请注意,Postgres建立在基础操作系统提供的语言环境设置的基础上,因此您需要为要使用的每个语言环境生成语言环境。在这里这里有关SO的更多相关答案。

但是,正如@Craig已经提到的那样索引是这种情况下的瓶颈。在涉及字符数据的许多情况下,索引的排序规则必须与应用的运算符的排序规则匹配。

您可以COLLATE在索引中使用说明符以生成匹配的索引。如果要在同一表中混合数据,则部分索引可能是理想的选择。

例如,具有国际字符串的表:

CREATE TABLE string (
   string_id serial
  ,lang_id   int NOT NULL
  ,string    text NOT NULL
);

而且您一次最多只对一种语言感兴趣:

SELECT *
FROM   string
WHERE  lang_id = 5  -- 5 being German / Germany here
AND    string > 'foo' COLLATE "de_DE"
ORDER  BY string COLLATE "de_DE";

然后创建部分索引,例如:

CREATE INDEX string_string_lang_id_idx ON string (string COLLATE "de_DE")
WHERE lang_id = 5;

一种您需要的每种语言。

实际上,对于这样的表,继承可能是一种更好的方法。然后,您可以在每个继承的表上具有一个纯索引,该索引仅包含单个语言环境的字符串。当然,您需要熟悉继承表的特殊规则。


1
默认情况下,是否对任何新数据库都使用C语言环境(准确地说是“非语言环境”)?
杰克·道格拉斯

1
@JackDouglas:不,我只会在特殊情况下这样做。通常,在该地方使用通用语言环境更为实用。
Erwin Brandstetter 2014年

13

我建议您选择提供默认Unicode顺序的排序规则。这样,即使您不覆盖每个查询中的排序规则,您也可以获得合理的结果。不幸的是,大多数(所有?)操作系统都没有提供一个简单地命名为“默认Unicode”或类似名称的语言环境,因此您将不得不猜测和/或研究一个不错的选择。例如,在Linux / glibc上,de_DE.utf8或en_US.utf8语言环境只是通过默认行为,因此这两个都是不错的选择。

我认为使用C语言环境不是一个好主意,因为那样的话,应用程序的默认行为将毫无用处。而且您可能无法通过大小写转换操作获得正确的行为。

(在查询中覆盖排序规则没有太多开销。这只是一个解析时操作。)


理智的默认设置可能会减轻痛苦。–
欧文·布兰德斯特

1
当前,我正在测试数据库中使用es_CL.utf8,但是由于您的回答,我看上去有些多了,发现这utf8_unicode_ci是要走的路

0

我们在docker容器中使用postgres,因此我们总是有ICU可用,并und-x-icu默认使用。

在第23.2.2.2.2节中提到了这一点postres文档的ICU归类提到:

und-x-icu(表示“ undefined”)
ICU“ root”排序规则。使用它来获得合理的与语言无关的排序顺序。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.