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'textMacのフィールドとしてキャストされていない可能性はありますか?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。それらを使用してそれぞれのボックスで明示的に照合を強制すると、異なる並べ替え順序が表示されます:
カーティスポー

そして、私は問題を説明するかもしれないアップデートを投稿しました、しかし、私にとって、それは単に謎を深めます。:そして、私は今、この見つけたstackoverflow.com/questions/19967555/...:このstackoverflow.com/questions/27395317/...
カーティス・ポー

7
残念ながら、PostgresはOSの照合実装を使用しており、この種の動作をOSに依存させています(個人的にはバグと考えています-DBMSはOSに関係なく同一に動作するはずです)。したがって、これはDebianとOSXのシステムライブラリの違いに
要約されます-a_horse_with_no_name

1
ソート順が他の順序と一致しない場合、Postgresとシステムの他の部分との間で意見の相違があります。私も同じ振る舞いを好みますが、システムロケールに従うことをバグとは呼びません。最終的に、同一のロケールはOS全体で同一に動作するはずです。Debianのロケールが右に思える(他のいくつかの説明がない限り)、Appleは障害であると思われます。
アーウィンブランドステッター

回答:


16

それでen_US.UTF-8en_US.utf8異なるソート順がありますか?

いいえ、これらは両方とも同じで、命名規則が異なります。

Debianバージョンが大文字と小文字を区別しないように見え、OS Xバージョンがそうではない理由に私は不思議に思っています。

はい。それで合っています。これはMacのデフォルトの動作です。照合は、BSD-ish OS(OSXを含む)でのUTF8エンコードには機能しません。

以下がそれを証明するリファレンスです。

ソート順の問題(UTF8ロケールは機能しません

以下のようa_horse_with_no_nameは言った、PostgresはOSからの照合の実装を使用しています。両方のオペレーティングシステムで同じ結果を得る方法はありません。

あなたの場合、次のようにすることができます(多分言いました)ORDER BY lower(fieldname)


2
ORDER BY function()潜在的に大きな結果セットで使用するときは、パフォーマンスを確認してください-ソートに使用されているインデックスを停止するため、追加のソート操作(おそらくディスク上)をほぼ確実に引き起こし、クエリを攻撃するクエリプランナーの方法をより広く変更する可能性があります。
デビッドスピレット

@David Spillett:Order関数については正しいです。私の答えは、OPがiMacとDebianで異なるソート方法を持っている理由にもっと焦点を合わせていると思います。ありがとう
-JSapkota

1
はい、あなたの答えはまったく問題なく、質問を完全にカバーしています。「クエリプランに影響を与える可能性のある変更後の実際のデータでのテスト」に言及することは、忘れがちであるため(そして多くの場合、人々が頻繁に行う)データベース作業が初めての人の場合でも、それを知りません。
デビッドスピレット
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.