为什么我的 PostgreSQL ORDER BY 不区分大小写?

Cur*_*Poe 32 postgresql collation

我在 Debian 上运行 Postgres 9.4.4,我得到以下ORDER BY行为:

veure_test=# show LC_COLLATE;
 lc_collate  
-------------
 en_US.UTF-8
(1 row)

veure_test=# SELECT regexp_split_to_table('D d a A c b CD Capacitor', ' ') ORDER BY 1;
 regexp_split_to_table 
-----------------------
 a
 A
 b
 c
 Capacitor
 CD
 d
 D
(8 rows)
Run Code Online (Sandbox Code Playgroud)

并且uname -a

Linux ---- 3.2.0-4-amd64 #1 SMP Debian 3.2.65-1 x86_64 GNU/Linux
Run Code Online (Sandbox Code Playgroud)

但是,在我的 iMac 上,使用 Postgres 9.3.4,我得到以下信息:

veure_test=# show LC_COLLATE;
 lc_collate  
-------------
 en_US.UTF-8
(1 row)

veure_test=# SELECT regexp_split_to_table('D d a A c b CD Capacitor', ' ') ORDER BY 1;
 regexp_split_to_table 
-----------------------
 A
 CD
 Capacitor
 D
 a
 b
 c
 d
(8 rows)
Run Code Online (Sandbox Code Playgroud)

uname -a

Darwin ---- 14.4.0 Darwin Kernel Version 14.4.0: Thu May 28 11:35:04 PDT 2015; root:xnu-2782.30.5~1/RELEASE_X86_64 x86_64
Run Code Online (Sandbox Code Playgroud)

我很困惑为什么 Debian 版本似乎不区分大小写,而 OS X 版本不是。我遗漏了什么,或者我需要提供什么其他信息?

更新:在我的 Mac 上,pg_collation表格显示我有一个en_US.UTF-8排序规则,但在 Debian 上,我有一个en_US.utf8排序规则。因此,在我的 Mac 上:

veure_test=# with foo as (
SELECT regexp_split_to_table('D d a A c b CD Capacitor', ' ') as bar
   )
SELECT bar FROM foo
ORDER BY bar collate "en_US.UTF-8";                                                                                                                                                                                      
    bar    
-----------
 A
 CD
 Capacitor
 D
 a
 b
 c
 d
(8 rows)
Run Code Online (Sandbox Code Playgroud)

在 Debian 上:

veure_test=# with foo as (
SELECT regexp_split_to_table('D d a A c b CD Capacitor', ' ') as bar
   )
SELECT bar FROM foo
ORDER BY bar collate "en_US.utf8";
    bar    
-----------
 a
 A
 b
 c
 Capacitor
 CD
 d
 D
(8 rows)
Run Code Online (Sandbox Code Playgroud)

那么en_US.UTF-8en_US.utf8有不同的排序顺序吗?

ato*_*pas 23

那么en_US.UTF-8en_US.utf8有不同的排序顺序吗?

不,这两者是相同的,只是命名约定不同。

我很困惑为什么 Debian 版本似乎不区分大小写,而 OS X 版本不是。

是的,你是对的。这是 Mac 上的默认行为。排序规则不适用于任何 BSD-ish 操作系统(包括 OSX)进行UTF8编码。

这里有一个参考来证明:

排序顺序问题(UTF8 语言环境不起作用)

正如a_horse_with_no_name所说,Postgres 使用来自操作系统的整理实现。无法在两个操作系统上获得相同的结果。

在你的情况,你可能(或许我说的)这样做:ORDER BY lower(fieldname)

  • 在潜在的大型结果集上使用“ORDER BY 函数()”时请注意验证性能 - 因为它会停止用于排序的索引,它几乎肯定会导致额外的排序操作(可能在磁盘上)并且它可能会改变查询计划器的更广泛地攻击您的查询的方法。 (3认同)