尽管 Postgres 中的排序规则相同,但排序不同

nun*_*nos 3 postgresql collation

尽管使用的排序规则显然相同,但我对带有变音符号的项目得到了不同的排序结果。

因此,在我的 mac 盒中安装Postgress.app进行开发后,我创建了下表:

create table names (
    id int primary key,
    name varchar
)
Run Code Online (Sandbox Code Playgroud)

然后插入一些值

insert into names values (1, "Francisco");
insert into names values (2, "Ana");
insert into names values (3, "Ágata");
Run Code Online (Sandbox Code Playgroud)

然后像这样查询它们:

select name from names order by name;
Run Code Online (Sandbox Code Playgroud)

我得到了一个错误的排序顺序,如下所示:

Ana
Francisco
Ágata
Run Code Online (Sandbox Code Playgroud)

我可以确认

select datname, 
       datcollate
from pg_database;
Run Code Online (Sandbox Code Playgroud)

datcollate所有数据库值en_US.UTF-8

为了帮助我调试这个问题,我快速启动了一个具有相同数据、查询和整理的 RDS 实例,但这次我得到了正确的预期排序顺序:

Ágata
Ana
Francisco
Run Code Online (Sandbox Code Playgroud)

我在这里缺少什么,如何在我的开发框中配置 postgres 以使其按预期运行?

Dan*_*ité 6

PostgreSQL 使用操作系统作为其语言环境(至少libc作为排序规则提供者,否则icu可能会使用),不幸的是,不同的操作系统对相同的 UTF-8 语言环境名称给出不一致的排序结果。

UTF-8 与 Postgres.app 的排序规则没有按预期排序的事实是他们问题跟踪器上的一个旧的开放项:排序顺序问题(UTF8 语言环境不起作用)。除非 Apple 修复 macOS,否则它无法真正修复,而且到目前为止还没有发生。有关提及该问题的 2012 年问题,请参阅不同机器(相同语言环境)上 Postgres 实例之间的排序差异

我在这里缺少什么,如何在我的开发框中配置 postgres 以使其按预期运行?

您的选择:

  • 对开发和生产使用相同的操作系统,可能是虚拟化的。

  • 使用 ICU 整理。它们在所有操作系统中的排序都相同,但从 PG 版本 12 开始,它们只能COLLATE在列或表达式级别(而不是数据库级别)与显式子句一起使用。

  • 使用“C”或“C.UTF-8”排序规则,它们按代码点二进制排序。它们不提供语言感知的排序顺序,但它们更快、不可变且跨操作系统一致。