¿Por qué mi ORDEN de PostgreSQL no distingue entre mayúsculas y minúsculas?


27

Tengo Postgres 9.4.4 ejecutándose en Debian y obtengo el siguiente ORDER BYcomportamiento:

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)

Y uname -a:

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

Sin embargo, en mi iMac, con Postgres 9.3.4, obtengo lo siguiente:

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)

Y el 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

Me desconcierta por qué la versión de Debian parece no distinguir entre mayúsculas y minúsculas y la versión de OS X no. ¿Qué me estoy perdiendo o qué otra información necesito proporcionar?

Actualización : en mi Mac, la pg_collationtabla muestra que tengo una en_US.UTF-8clasificación, pero en Debian, tengo una en_US.utf8clasificación. Por lo tanto, en mi 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)

Y en 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)

Entonces, ¿ en_US.UTF-8y en_US.utf8tiene diferentes órdenes de clasificación?


No tengo una Mac para probar, así que estoy disparando en la oscuridad aquí ... ¿ 'D d a A c b CD Capacitor'Hay alguna posibilidad de que la cadena no se arroje como un textcampo en la Mac? IE, intenta SELECT regexp_split_to_table('D d a A c b CD Capacitor'::text, ' ') ORDER BY 1;ver qué pasa ...
Chris

Mismo resultado. En otras noticias, resulta que select * from pg_collationmuestra el cuadro de Debian en_US.utf8, mientras que el OS X sí en_US.UTF-8. El uso de estos para forzar explícitamente la ordenación en los cuadros respectivos muestra diferentes órdenes de clasificación :(
Curtis Poe

Y he publicado una actualización que podría explicar el problema, pero para mí, simplemente profundiza el misterio. Y ahora he encontrado esto: stackoverflow.com/questions/19967555/… y esto: stackoverflow.com/questions/27395317/…
Curtis Poe

77
Lamentablemente, Postgres utiliza la implementación de intercalación del sistema operativo que hace que este tipo de comportamiento dependa del sistema operativo (lo que personalmente considero un error: un DBMS debe comportarse de manera idéntica independientemente del sistema operativo). Así que esto se reduce a diferencias en las bibliotecas del sistema entre Debian y OSX
a_horse_with_no_name

1
Habrá desacuerdos entre Postgres y otras partes del sistema si el orden de clasificación no coincide con el resto. Yo también prefiero un comportamiento idéntico, pero no lo llamaría un error para seguir la configuración regional del sistema. Finalmente, las configuraciones regionales idénticas deberían comportarse de manera idéntica en el sistema operativo. La configuración regional de Debian parece correcta , Apple parece tener la culpa (a menos que haya otra explicación).
Erwin Brandstetter

Respuestas:


16

Entonces, ¿ en_US.UTF-8y en_US.utf8tiene diferentes órdenes de clasificación?

No, estos dos son iguales, solo una convención de nomenclatura diferente.

Me desconcierta por qué la versión de Debian parece no distinguir entre mayúsculas y minúsculas y la versión de OS X no.

Sí, estás en lo correcto. Este es el comportamiento predeterminado en Mac. Las intercalaciones no funcionan en ningún sistema operativo BSD-ish (incluido OSX) para la UTF8codificación.

Aquí hay una referencia para demostrar que:

Problemas con el orden de clasificación (las configuraciones regionales UTF8 no funcionan

Como dijo a_horse_with_no_name , Postgres usa la implementación de intercalación del sistema operativo. No hay forma de obtener el mismo resultado en ambos sistemas operativos.

En su caso, usted puede (i dicho tal vez) hacer como esto: ORDER BY lower(fieldname).


2
Tenga cuidado de verificar el rendimiento cuando lo use ORDER BY function()en conjuntos de resultados potencialmente grandes, ya que detiene el uso de un índice para la clasificación, seguramente causará una operación de clasificación adicional (posiblemente en el disco) y puede cambiar el método del planificador de consultas para atacar su consulta más ampliamente .
David Spillett

@David Spillett: Tiene razón acerca de la función Orden. Creo que mi respuesta está más centrada en por qué el OP está teniendo una forma de clasificación diferente en iMac y Debian. Gracias
JSapkota

1
Sí, su respuesta está perfectamente bien y cubre la pregunta por completo. Sin embargo, mencionar "probar con datos reales después de cambios que podrían afectar el plan de consulta" se ha convertido en una reacción habitual en mí (al igual que mencionar las pruebas en cualquier discusión sobre copias de seguridad, etc.), ya que es fácil de olvidar (y la gente suele hacerlo) o Ni siquiera lo sé en el caso de las personas más nuevas en el trabajo de base de datos.
David Spillett
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.