Por que meu PostgreSQL ORDER BY não diferencia maiúsculas de minúsculas?


27

Tenho o Postgres 9.4.4 em execução no Debian e recebo o seguinte ORDER BYcomportamento:

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)

E uname -a:

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

No entanto, no meu iMac, com o Postgres 9.3.4, recebo o seguinte:

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)

E o 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

Estou perplexo com o motivo pelo qual a versão Debian parece não fazer distinção entre maiúsculas e minúsculas e a versão do OS X não. O que estou faltando ou que outras informações eu preciso fornecer?

Atualização : No meu Mac, a pg_collationtabela mostra que tenho um en_US.UTF-8agrupamento, mas no Debian, tenho um en_US.utf8agrupamento. Assim, no meu 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)

E no 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)

Então, en_US.UTF-8e en_US.utf8tem ordens de classificação diferentes?


Não tenho um Mac para testar, por isso estou filmando no escuro aqui ... Alguma chance de a corda 'D d a A c b CD Capacitor'não estar sendo lançada como um textcampo no Mac? IE, tente SELECT regexp_split_to_table('D d a A c b CD Capacitor'::text, ' ') ORDER BY 1;ver o que acontece ...
Chris

Mesmo resultado. Em outras notícias, acontece que select * from pg_collationmostra a caixa Debian en_US.utf8, enquanto o OS X possui en_US.UTF-8. Usando os forçar explicitamente agrupamento nas caixas respectivas mostra diferentes ordens de classificação :(
Curtis Poe

E eu publiquei uma atualização que pode explicar o problema, mas para mim, isso apenas aprofunda o mistério. E eu tenho encontrado agora isto: stackoverflow.com/questions/19967555/... e isso: stackoverflow.com/questions/27395317/...
Curtis Poe

7
Infelizmente, o Postgres usa a implementação de agrupamento do sistema operacional, o que torna esse tipo de comportamento dependente do sistema operacional (que eu pessoalmente considero um bug - um DBMS deve se comportar de forma idêntica, independentemente do sistema operacional). Portanto, esta se resume a diferença nas bibliotecas sistema entre Debian e OSX
a_horse_with_no_name

11
Haverá desacordo entre o Postgres e outras partes do sistema se a ordem de classificação não estiver alinhada com o restante. Eu também prefiro comportamento idêntico, mas não chamaria de bug seguir a localidade do sistema. Por fim, locais idênticos devem se comportar de forma idêntica no sistema operacional. O local do Debian parece correto , a Apple parece estar com falha (a menos que haja outra explicação).
Erwin Brandstetter

Respostas:


16

Então, en_US.UTF-8e en_US.utf8tem ordens de classificação diferentes?

Não, ambos são iguais, apenas uma convenção de nomenclatura diferente.

Estou perplexo com o motivo pelo qual a versão Debian parece não fazer distinção entre maiúsculas e minúsculas e a versão do OS X não.

Sim você está correto. Esse é o comportamento padrão no Mac. Os agrupamentos não funcionam em nenhum sistema operacional BSD (incluindo OSX) para UTF8codificação.

Aqui está uma referência para provar que:

Problemas com a ordem de classificação (os códigos de idioma UTF8 não funcionam

Como um a_horse_with_no_name disse, o Postgres usa a implementação de agrupamento do sistema operacional. Não há como obter o mesmo resultado nos dois sistemas operacionais.

No seu caso, você pode (eu disse talvez) fazer assim: ORDER BY lower(fieldname).


2
Tome cuidado para verificar o desempenho ao usar ORDER BY function()em conjuntos de resultados potencialmente grandes - porque ele interrompe a utilização de um índice para a classificação, quase certamente causará uma operação de classificação extra (possivelmente em disco) e pode alterar o método do planejador de consulta de atacar sua consulta mais amplamente .
David Spillett

@ David Spillett: Você está certo sobre a função Order. Eu acho que minha resposta está mais focada em por que o OP está tendo uma maneira diferente de classificação no iMac e no Debian. Graças
JSapkota

11
Sim, sua resposta está perfeitamente correta e cobre a questão completamente. Mencionar "testar com dados reais após alterações que possam afetar o plano de consulta" se tornou uma reação habitual para mim (assim como mencionar o teste em qualquer discussão sobre backups e assim por diante), pois é fácil esquecer (e as pessoas costumam fazer) ou nem sei no caso de pessoas mais novas no trabalho de banco de dados.
David Spillett
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.