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


27

我在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)

uname -a

Linux ---- 3.2.0-4-amd64 #1 SMP Debian 3.2.65-1 x86_64 GNU/Linux

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

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)

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

我对为什么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)

在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)

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


我没有要测试的Mac,所以我在这里黑暗中拍摄...可能'D d a A c b CD Capacitor'不会text在Mac上将字符串转换为字段吗?IE浏览器,尝试SELECT regexp_split_to_table('D d a A c b CD Capacitor'::text, ' ') ORDER BY 1;看看会发生什么...
克里斯

结果相同。在其他消息中,结果select * from pg_collation显示Debian盒中有en_US.utf8,而OS X中有en_US.UTF-8。使用那些在各个框上显式强制排序规则将显示不同的排序顺序:(
Curtis Poe15年

而且我已经发布了可能解释该问题的更新,但是对我来说,这只会加深神秘感。而且我现在发现这一点:stackoverflow.com/questions/19967555/...这:stackoverflow.com/questions/27395317/...
柯蒂斯坡

7
不幸的是,Postgres使用了OS的归类实现,这使这种行为依赖于OS(我个人认为是一个错误-无论OS是什么,DBMS的行为都应相同)。因此,这归结为Debian和OSX之间的系统库之间的差异
a_horse_with_no_name 2015年

1
如果排序顺序与其余部分不一致,则Postgres和系统其他部分之间将存在分歧。我也更喜欢相同的行为,但是我不会称其为遵循系统区域设置的错误。最终,相同的语言环境在整个OS上的行为应相同。在Debian的区域似乎正确的,苹果似乎是在错误(除非有一些其他的解释)。
Erwin Brandstetter 2015年

Answers:


16

那么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)


2
ORDER BY function()在可能较大的结果集上使用时,请务必验证性能-因为它会停止将索引用于排序,因此几乎可以肯定会引起额外的排序操作(可能在磁盘上),并且可能会改变查询计划者更广泛地攻击您的查询的方法。
David Spillett

@David Spillett:您对Order函数是正确的。我认为我的答案更集中于为什么OP在iMac和Debian中具有不同的排序方式。谢谢
JSapkota '16

1
是的,您的回答非常好,可以完全覆盖问题。尽管很容易忘记(并且人们经常这样做),但提到“在可能影响查询计划的更改后使用真实数据进行测试”已经成为我的习惯性反应(就像在任何有关备份的讨论中提到测试,等等)。对于刚接触数据库工作的人甚至都不知道。
David Spillett
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.