Dlaczego w mojej PostgreSQL ORDER BY nie jest rozróżniana wielkość liter?


27

Mam Postgres 9.4.4 działający na Debianie i otrzymuję następujące ORDER BYzachowanie:

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)

I uname -a:

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

Jednak na moim komputerze iMac z Postgres 9.3.4 otrzymuję:

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)

I 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

Dziwię się, dlaczego wersja Debiana wydaje się nie rozróżniać wielkości liter, a wersja OS X nie. Czego mi brakuje lub jakie inne informacje muszę podać?

Aktualizacja : Na moim komputerze Mac pg_collationtabela pokazuje, że mam en_US.UTF-8zestawienie, ale w Debianie mam en_US.utf8zestawienie. Tak więc na moim komputerze 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)

A na Debianie:

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)

Więc en_US.UTF-8i en_US.utf8masz różne porządki sortowania?


Nie mam komputera Mac do przetestowania, więc strzelam tutaj w ciemności ... Czy jest szansa, że ​​struna 'D d a A c b CD Capacitor'nie zostanie rzucona jak textpole na komputerze Mac? IE, spróbuj SELECT regexp_split_to_table('D d a A c b CD Capacitor'::text, ' ') ORDER BY 1;zobaczyć, co się stanie ...
Chris

Ten sam wynik. W innych wiadomościach okazuje się, że select * from pg_collationpokazuje to okno Debiana en_US.utf8, podczas gdy OS X tak en_US.UTF-8. Używanie ich do wymuszania sortowania w odpowiednich polach pokazuje różne porządki sortowania :(
Curtis Poe

I opublikowałem aktualizację, która może wyjaśnić problem, ale dla mnie to tylko pogłębia tajemnicę. I teraz znalazłem to: stackoverflow.com/questions/19967555/… i to: stackoverflow.com/questions/27395317/…
Curtis Poe

7
Niestety Postgres korzysta z implementacji sortowania z systemu operacyjnego, która uzależnia takie zachowanie systemu operacyjnego (co osobiście uważam za błąd - DBMS powinien zachowywać się identycznie niezależnie od systemu operacyjnego). Sprowadza się to zatem do różnic w bibliotekach systemowych między Debianem a OSX
a_horse_w_na_nazwa

1
Nie będzie zgody między Postgres a innymi częściami systemu, jeśli kolejność sortowania nie będzie zgodna z resztą. Ja też wolę identyczne zachowanie, ale nie nazwałbym tego błędem, aby śledzić ustawienia regionalne systemu. Ostatecznie identyczne ustawienia regionalne powinny zachowywać się identycznie w całym systemie operacyjnym. Locale Debian wydaje się prawo , Apple wydaje się winy (o ile nie ma innego wyjaśnienia).
Erwin Brandstetter

Odpowiedzi:


16

Więc en_US.UTF-8i en_US.utf8masz różne porządki sortowania?

Nie, oba są takie same, tylko inna konwencja nazewnictwa.

Dziwię się, dlaczego wersja Debiana wydaje się nie rozróżniać wielkości liter, a wersja OS X nie.

Tak, masz rację. Jest to domyślne zachowanie na komputerze Mac. Zestawienia nie działają na żadnym systemie operacyjnym BSD (w tym OSX) do UTF8kodowania.

Oto odniesienie, aby udowodnić, że:

Problemy z kolejnością sortowania (ustawienia regionalne UTF8 nie działają

Jak powiedział a_horse_with_no_name , Postgres używa implementacji sortowania z systemu operacyjnego. Nie ma sposobu, aby uzyskać ten sam wynik w obu systemach operacyjnych.

W twoim przypadku może (powiedziałem może) zrobić tak: ORDER BY lower(fieldname).


2
Należy zachować ostrożność podczas sprawdzania wydajności w przypadku ORDER BY function()potencjalnie dużych zestawów wyników - ponieważ zatrzymuje indeks używany do sortowania, prawie na pewno spowoduje dodatkową operację sortowania (prawdopodobnie na dysku) i może zmienić metodę planisty zapytań na szersze atakowanie zapytania .
David Spillett,

@David Spillett: Masz rację co do funkcji zamówienia. Myślę, że moja odpowiedź jest bardziej skoncentrowana na tym, dlaczego OP ma inny sposób sortowania w iMacu i Debianie. Dzięki
JSapkota,

1
Tak, twoja odpowiedź jest całkowicie w porządku i całkowicie obejmuje pytanie. Wzmianka o „testowaniu rzeczywistych danych po zmianach, które mogą wpłynąć na plan zapytań” stała się jednak we mnie nawykową reakcją (podobnie jak wspomnienie o testowaniu w dowolnej dyskusji na temat kopii zapasowych itp.), Ponieważ łatwo jest o tym zapomnieć (a ludzie często to robią) lub nawet nie wiem w przypadku osób nowszych do pracy z bazami danych.
David Spillett,
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.