【问题标题】:Postgres seems to be ignoring my default collationPostgres 似乎忽略了我的默认排序规则
【发布时间】:2020-01-27 19:51:48
【问题描述】:

我想将 postgres 默认设置为按排序规则 en-US-x-icu 排序,因此我将 LC_CTYPE 和 LC_COLLATE 环境变量设置为该值。 Postgres 似乎看到了它们,并说它正在使用该排序规则:

:mctapi=# select datname, datcollate, datctype from pg_database where datname='mctapi';
 datname | datcollate  |  datctype
---------+-------------+-------------
 mctapi  | en-US-x-icu | en-US-x-icu

:mctapi=# show lc_collate;
 lc_collate
-------------
 en-US-x-icu
(1 row)

:mctapi=# show lc_ctype;
  lc_ctype
-------------
 en-US-x-icu
(1 row)

但是,除非我明确地将 en-US-x-icu 设置为排序规则,否则我会得到 C 排序规则:

:mctapi=# select distinct organization_name from plans order by organization_name limit 5;
            organization_name
------------------------------------------
 AMH Health
 ATRIO Health Plans
 Aetna Medicare
 AgeRight Advantage
 AgeRight Advantage Health Plan (HMO SNP)
(5 rows)

:mctapi=# select distinct organization_name collate "en-US-x-icu" from plans order by organization_name limit 5;
            organization_name
------------------------------------------
 Aetna Medicare
 AgeRight Advantage
 AgeRight Advantage Health Plan (HMO SNP)
 Allwell
 AMH Health
(5 rows)

:mctapi=# select distinct organization_name collate "C" from plans order by organization_name limit 5;
            organization_name
------------------------------------------
 AMH Health
 ATRIO Health Plans
 Aetna Medicare
 AgeRight Advantage
 AgeRight Advantage Health Plan (HMO SNP)
(5 rows)

我必须做些什么才能让 postgres 在我的数据库中使用 en-US-x-icu 作为默认排序而不显式设置 collat​​e 参数?为什么即使我要求它按en-US-x-icu 排序,它还是按C 排序?

(对于它的价值:有问题的数据库是在 docker compose 上运行的 mdillon/postgis:10-alpine 图像。我真的不想离开 alpine 图像,但如果无法使用它,我可以。)

(更新:更改为非高山图像将排序更改为 en_US.UTF8,如下面的 postgres docker 图像文档中所述,并修复了此表的排序顺序。我仍然想知道为什么我的设置LC_COLLATE 并没有改变 alpine 中的排序顺序,因为我宁愿使用那个图像)

(更新2:数据库是在没有编码选项的情况下创建的,我没有手动更新pg_database,我唯一改变的是LC_CTYPE和LC_COLLATE环境变量。

这个版本的 postgres 是用 --with-icu 编译的,你可以在这里看到:https://github.com/docker-library/postgres/blob/master/10/alpine/Dockerfile#L113 和 https://www.postgresql.org/docs/10/collation.html#COLLATION-MANAGING 在我看来,ICU 语言环境应该可以在我的 postgres 版本中使用。

如果我取消设置 LC_COLLATE 和 LC_CTYPE 并重新创建我的数据库,它的 collat​​e 和 ctype 值可能是 en_US.UTF8,但包含数据库的 Alpine 图像中不存在该区域设置,离开这种情况:

:mctapi=# select datname, datcollate, datctype from pg_database where datname='mctapi';
 datname | datcollate |  datctype
---------+------------+------------
 mctapi  | en_US.utf8 | en_US.utf8
(1 row)

:mctapi=# select distinct organization_name collate "en_US.utf8" from plans order by organization_name limit 5;
ERROR:  collation "en_US.utf8" for encoding "UTF8" does not exist

)

(最终更新:我同意 Laurenz 关于 alpine 上的 postgres 在语言环境方面普遍存在的问题,我非常感谢他对这个问题的关注。我仍然不明白为什么 ICU 不能作为 LC_COLLATE 工作,或者为什么它确实在明确提及时起作用,但我刚刚接受了我不能使用 alpine docker 映像并已移至基于 debian 的映像。)

参考资料:

1:https://www.postgresql.org/docs/10/locale.html

2:https://www.postgresql.org/docs/10/collation.html

3:https://www.postgresql.org/docs/10/sql-expressions.html#SQL-SYNTAX-COLLATE-EXPRS

4:https://wiki.postgresql.org/wiki/FAQ#Why_do_my_strings_sort_incorrectly.3F

5:https://github.com/docker-library/docs/tree/master/postgres#locale-customization

【问题讨论】:

  • 创建数据库时。也许您将 CREATE 语法与编码一起使用。 DB 编码优于服务器编码。
  • 不,数据库不是使用编码创建的,它是一个“CREATE DATABASE mctapi”命令,没有其他选项

标签: sql database postgresql


【解决方案1】:

您不能在CREATE DATABASE 中使用除 C 库的排序规则之外的任何其他内容。这是一个未记录的限制,可能会在 v13 中取消。有关参考,请参阅 this 和 this 线程。

所以起初我很惊讶您能够创建该数据库,因为您的排序规则是 ICU 排序规则,通常只能通过单独的 ICU 库获得。

我发现一个Silverstripe issue 抱怨完全相同的事情,所以至少你并不孤单。那里的讨论没有任何结果,因为他们似乎既不了解 Alpine Linux 也不了解 PostgreSQL。

基于您的 cmets 的进一步调查表明,Alpine Linux 不使用 glibc,而是使用 musl 作为 C 库。似乎musl的排序规则的实现还没有完全完成,至少我在roadmap中找到了这个:

musl 1.2.0 的里程碑目标

构成“musl 1.2.0”的以下暂定目标是 已确立的。目前没有 1.2.0 的预计发布日期。

[...] - 改进了区域设置和多语言支持

LC_COLLATE 支持除简单代码点顺序之外的排序顺序

这似乎解释了你的经历。

使用具有工作排序规则的不同 Linux 发行版是前进的方向。

【讨论】:

【解决方案2】:

仅此功能的链接状态https://commitfest.postgresql.org/25/2256/

【讨论】:

  • 谢谢! 9 个月内没有移动 - 这是否表明它已经停滞不前?我不知道正常的 postgres 时间表或做法是什么。
猜你喜欢
  • 1970-01-01
  • 2016-10-31
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-11-11
  • 2017-03-04
相关资源
最近更新 更多