Como estou projetando um banco de dados que armazena dados em diferentes idiomas (usando UTF-8), acho que a melhor maneira de exibir os resultados da consulta é ordená-los de acordo com o idioma do usuário durante a consulta ( porque há mais de um maneiras corretas de fazer isso ), da seguinte maneira:
SELECT a < b COLLATE "de_DE" FROM test1;
Supondo que essa seja a maneira correta de trabalhar com dados internacionais, qual é o melhor agrupamento para o próprio banco de dados? A documentação do PostgreSQL diz :
Os agrupamentos C e POSIX especificam o comportamento "tradicional C", no qual apenas as letras ASCII "A" a "Z" são tratadas como letras e a classificação é feita estritamente pelos valores de bytes do código de caracteres.
Eu acho que é a melhor escolha neste caso, ou estou errado?
(Pergunta bônus: é muito lento para selecionar o agrupamento na própria consulta?).
Respostas:
O
C
agrupamento é a escolha certa.Tudo é um pouco mais rápido sem local. E como nenhum agrupamento está correto, crie o banco de dados sem agrupamento, ou seja, com
C
.Pode ser uma dor ter que fornecer um agrupamento para muitas operações. Porém, não deve haver uma diferença notável na velocidade entre o agrupamento padrão e um agrupamento ad-hoc. Afinal, são apenas dados não classificados e as regras de ordenação são aplicadas na classificação.
Esteja ciente de que o Postgres se baseia nas configurações de localidade fornecidas pelo sistema operacional subjacente; portanto, é necessário gerar localidades geradas para cada localidade a ser usada. Mais respostas relacionadas ao SO aqui e aqui .
No entanto, como o @Craig já mencionado , os índices são o gargalo nesse cenário. O agrupamento do índice deve corresponder ao agrupamento do operador aplicado em muitos casos que envolvem dados de caracteres.
Você pode usar o
COLLATE
especificador em índices para produzir índices correspondentes. Índices parciais podem ser a escolha perfeita se você estiver misturando dados na mesma tabela.Por exemplo, uma tabela com cadeias internacionais:
E você está interessado principalmente em um idioma por vez:
Em seguida, crie índices parciais como:
Um para cada idioma que você precisa.
Na verdade, a herança pode ser uma abordagem superior para uma tabela como esta. Em seguida, você pode ter um índice simples em cada tabela herdada contendo apenas cadeias de caracteres para um único código de idioma. Você precisa estar confortável com as regras especiais para tabelas herdadas, é claro.
fonte
Sugiro que você escolha um agrupamento que forneça o pedido Unicode padrão. Dessa forma, você obtém resultados sensatos, mesmo que não substitua o agrupamento em cada consulta. Infelizmente, a maioria dos sistemas operacionais (todos?) Não fornece um código de idioma simplesmente denominado "Unicode padrão" ou algo parecido; portanto, você terá que adivinhar e / ou pesquisar uma boa opção. Por exemplo, no Linux / glibc, os códigos de idioma de_DE.utf8 ou en_US.utf8 simplesmente passam pelo comportamento padrão, portanto, essas duas são boas escolhas.
Não acho que usar o código de idioma C seja uma boa idéia, pois o comportamento padrão do seu aplicativo será inútil. E você pode não ter um comportamento adequado das operações de conversão de caso.
(Substituir o agrupamento em uma consulta não tem muita sobrecarga. É apenas uma operação de tempo de análise.)
fonte
utf8_unicode_ci
é o caminho a percorrer .Usamos o postgres em um contêiner de docker, portanto, sempre temos a UTI disponível e usamos
und-x-icu
como padrão.Isso é mencionado no capítulo 23.2.2.2.2. Os agrupamentos de UTI dos documentos de pós-menção mencionam:
fonte