Warum unterscheidet mein PostgreSQL ORDER BY nicht zwischen Groß- und Kleinschreibung?


27

Ich habe Postgres 9.4.4 unter Debian und bekomme folgendes ORDER BYVerhalten:

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)

Und uname -a:

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

Auf meinem iMac mit Postgres 9.3.4 erhalte ich jedoch Folgendes:

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)

Und die 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

Es ist mir ein Rätsel, warum bei der Debian-Version die Groß- und Kleinschreibung nicht beachtet wird und bei der OS X-Version nicht. Was fehlt mir oder welche weiteren Informationen muss ich bereitstellen?

Update : Auf meinem Mac zeigt die pg_collationTabelle, dass ich eine en_US.UTF-8Kollatierung habe, aber auf Debian habe ich eine en_US.utf8Kollatierung. So auf meinem 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)

Und unter 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)

Also en_US.UTF-8und en_US.utf8unterschiedliche Sortierreihenfolgen?


Ich habe keinen Mac zum Testen, also schieße ich hier im Dunkeln ... Gibt es eine Chance, dass die Saite auf dem Mac 'D d a A c b CD Capacitor'nicht als textFeld geworfen wird ? IE, versuchen Sie SELECT regexp_split_to_table('D d a A c b CD Capacitor'::text, ' ') ORDER BY 1;und sehen, was passiert ...
Chris

Gleiches Ergebnis. In anderen Nachrichten stellt sich heraus, dass select * from pg_collationdie Debian-Box hat en_US.utf8, während das OS X hat en_US.UTF-8. Wenn Sie diese verwenden, um die Sortierung explizit für die jeweiligen Felder zu erzwingen, werden unterschiedliche Sortierreihenfolgen angezeigt: (
Curtis Poe,

Und ich habe ein Update gepostet, das das Problem möglicherweise erklärt, aber für mich vertieft es nur das Rätsel. Und ich habe jetzt Folgendes gefunden: stackoverflow.com/questions/19967555/… und dies: stackoverflow.com/questions/27395317/…
Curtis Poe

7
Leider verwendet Postgres die Kollatierungsimplementierung des Betriebssystems, die ein solches Verhalten vom Betriebssystem abhängig macht (was ich persönlich als Fehler betrachte - ein DBMS sollte sich unabhängig vom Betriebssystem identisch verhalten). Das läuft also auf Unterschiede in den Systembibliotheken zwischen Debian und OSX hinaus
a_horse_with_no_name

1
Es kommt zu Meinungsverschiedenheiten zwischen Postgres und anderen Teilen des Systems, wenn die Sortierreihenfolge nicht mit den übrigen übereinstimmt. Auch ich bevorzuge ein identisches Verhalten, aber ich würde es nicht als Fehler bezeichnen, dem Gebietsschema des Systems zu folgen. Letztendlich sollten sich identische Gebietsschemas unter allen Betriebssystemen identisch verhalten. Das Debian-Gebietsschema scheint zu stimmen , Apple scheint schuld zu sein (es sei denn, es gibt eine andere Erklärung).
Erwin Brandstetter

Antworten:


16

Also en_US.UTF-8und en_US.utf8unterschiedliche Sortierreihenfolgen?

Nein, beide sind gleich, nur eine andere Namenskonvention.

Es ist mir ein Rätsel, warum bei der Debian-Version die Groß- und Kleinschreibung nicht beachtet wird und bei der OS X-Version nicht.

Ja du hast Recht. Dies ist das Standardverhalten auf einem Mac. Kollatierungen funktionieren nicht auf BSD-basierten Betriebssystemen (einschließlich OSX) für die UTF8Codierung.

Hier ist ein Hinweis, um zu beweisen, dass:

Probleme mit der Sortierreihenfolge (UTF8-Gebietsschemas funktionieren nicht

Wie a_horse_with_no_name sagte, verwendet Postgres die Kollatierungsimplementierung vom Betriebssystem. Es gibt keine Möglichkeit, auf beiden Betriebssystemen dasselbe Ergebnis zu erzielen.

In Ihrem Fall können Sie (ich sagte , vielleicht) zu tun wie folgt aus : ORDER BY lower(fieldname).


2
Achten Sie darauf, die Leistung bei der Verwendung ORDER BY function()von potenziell großen Ergebnismengen zu überprüfen. Da ein Index für die Sortierung nicht mehr verwendet wird, führt dies mit ziemlicher Sicherheit zu einer zusätzlichen Sortierung (möglicherweise auf Datenträger) und kann die Methode des Abfrageplaners ändern, mit der Ihre Abfrage weiter angegriffen wird .
David Spillett

@ David Spillett: Sie haben Recht mit der Bestellfunktion. Ich denke, meine Antwort konzentriert sich mehr darauf, warum das OP in iMac und Debian eine andere Sortierweise hat. Vielen Dank
JSapkota

1
Ja, Ihre Antwort ist vollkommen in Ordnung und deckt die Frage vollständig ab. Die Erwähnung von "Testen mit realen Daten nach Änderungen, die sich auf den Abfrageplan auswirken könnten" ist für mich jedoch zur Gewohnheit geworden (ähnlich wie das Erwähnen von Tests in Diskussionen über Sicherungen usw.), da dies leicht zu vergessen ist (und die Leute dies häufig tun) oder weiß nicht einmal, bei Leuten, die neu in der Datenbank arbeiten.
David Spillett
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.