AskOverflow.Dev

AskOverflow.Dev Logo AskOverflow.Dev Logo

AskOverflow.Dev Navigation

  • Início
  • system&network
  • Ubuntu
  • Unix
  • DBA
  • Computer
  • Coding
  • LangChain

Mobile menu

Close
  • Início
  • system&network
    • Recentes
    • Highest score
    • tags
  • Ubuntu
    • Recentes
    • Highest score
    • tags
  • Unix
    • Recentes
    • tags
  • DBA
    • Recentes
    • tags
  • Computer
    • Recentes
    • tags
  • Coding
    • Recentes
    • tags
Início / dba / Perguntas / 240930
Accepted
rookie099
rookie099
Asked: 2019-06-20 06:22:07 +0800 CST2019-06-20 06:22:07 +0800 CST 2019-06-20 06:22:07 +0800 CST

PostgreSQL: diferença entre collations 'C' e 'C.UTF-8'

  • 772

No PostgreSQL, qual é a diferença entre collations Ce C.UTF-8?

Ambos aparecem em linhas de pg_collation. Talvez C.UTF-8seja o mesmo que Ccom a codificação UTF-8independentemente ou qual seja a codificação real de um banco de dados?

postgresql collation
  • 3 3 respostas
  • 15370 Views

3 respostas

  • Voted
  1. Best Answer
    Solomon Rutzky
    2019-06-20T09:24:11+08:002019-06-20T09:24:11+08:00

    A documentação do PostgreSQL deixa muito a desejar (só falando ? ).

    Para começar, há apenas uma codificação para um banco de dados específico, portanto, Ce C.UTF-8em seu banco de dados UTF-8, ambos estão usando a codificação UTF-8.

    Para agrupamentos libc : normalmente os nomes de agrupamentos, por convenção , são realmente nomes de duas partes da seguinte estrutura:

    {locale_name}.{encoding_name}

    Um "locale" (ou seja, "cultura") é o conjunto de regras específicas do idioma para classificação ( LC_COLLATE) e capitalização ( LC_CTYPE). Mesmo que às vezes haja sobreposição, isso realmente não tem nada a ver com a forma como esses dados são armazenados.

    Uma "codificação" é como os dados são armazenados (ou seja, qual seqüência de bytes equivale a qual caractere). Mesmo que às vezes haja sobreposição, isso realmente não tem nada a ver com as regras de classificação e capitalização de qualquer idioma específico que usa a codificação (algumas codificações podem ser usadas por vários idiomas que podem ter regras bastante diferentes em um ou ambos essas áreas).

    Para ilustrar, considere armazenar dados coreanos:

    • ko_KRé a localidade.
    • As codificações possíveis que funcionam com esta localidade são:
      • EUC_KR(Extended UNIX Code-KR)
      • JOHAB
      • UHC(Código Hangul Unificado / Windows949)
      • UTF8(codificação de 8 bits do Unicode)

    Considere também o seguinte, retirado da documentação " Collation Support: libc collations " (ênfase adicionada):

    Por exemplo, o sistema operacional pode fornecer um código de idioma chamado de_DE.utf8. initdbentão criaria um agrupamento nomeado de_DE.utf8para codificação UTF8... Ele também criaria um agrupamento com a .utf8tag retirada do nome. Portanto, você também pode usar o agrupamento sob o nome de_DE, que é menos complicado de escrever e torna o nome menos dependente de codificação ...

    ...

    Em qualquer banco de dados específico, apenas os agrupamentos que usam a codificação desse banco de dados são de interesse. Outras entradas em pg_collationsão ignoradas. Assim, um nome de agrupamento removido, como de_DEpode ser considerado exclusivo em um determinado banco de dados, mesmo que não seja globalmente exclusivo. O uso dos nomes de agrupamentos removidos é recomendado, pois isso fará com que uma coisa a menos que você precise alterar se decidir alterar para outra codificação de banco de dados. Observe, no entanto, que os agrupamentos default, Ce POSIXpodem ser usados ​​independentemente da codificação do banco de dados.

    Ou seja, em um banco de dados que usa a codificação UTF-8 en_USe en_US.UTF8são equivalentes. MAS, entre esse banco de dados e um banco de dados que usa a LATIN1codificação, os en_USagrupamentos não são equivalentes.

    Então, isso significa que Ce C.UTF-8são a mesma coisa?

    NÃO, isso seria muito fácil!!! A Cordenação é uma exceção ao comportamento indicado acima. O Cagrupamento é um conjunto simples de regras que está disponível independentemente da codificação do banco de dados, e o comportamento deve ser consistente entre as codificações (o que é possível apenas reconhecendo o alfabeto inglês dos EUA — "az" e "AZ" — como "letras" , e classificando por valor de byte, que deve ser o mesmo para as codificações disponíveis para você).

    O C.UTF-8agrupamento é, na verdade, um conjunto de regras ligeiramente aprimorado, em comparação com as Cregras básicas. Essa diferença pode ser vista em pg_collationuma vez que os valores para as colunas collcollatee collctypesão diferentes entre as linhas para Ce C.UTF-8.

    Eu montei um conjunto de consultas de teste para ilustrar algumas das semelhanças e diferenças entre esses dois agrupamentos, bem como em comparação com en_GB(e implicitamente en_GB.utf8). Comecei com as perguntas fornecidas na resposta de Daniel Vérité , aprimorei-as para ficar mais claro sobre o que está e o que não está sendo mostrado e adicionei algumas perguntas. Os resultados nos mostram que:

    1. Ce C.UTF-8são, na verdade, conjuntos de regras diferentes, mesmo que apenas ligeiramente diferentes, com base em seus respectivos valores nas colunas collcollatee em (consulta final)collctypepg_collation
    2. C.UTF-8expande os caracteres que são considerados "letras"
    3. C.UTF-8, ao contrário C(mas como en_GB), reconhece pontos de código Unicode inválidos (ou seja, U+0378) e os classifica para o topo
    4. C.UTF-8, like C(mas diferente en_GBde ), classifica caracteres de letras não inglesas dos EUA por ponto de código
    5. ucs_basicparece ser equivalente a C(o que é indicado na documentação)

    Você pode encontrar e executar as consultas em: db<>fiddle

    • 18
  2. Daniel Vérité
    2019-06-21T03:20:00+08:002019-06-21T03:20:00+08:00

    Talvez seja o caso de C.UTF-8 ser o mesmo que C com codificação UTF-8

    Não. Considere, por exemplo, estas diferenças em um banco de dados UTF-8, no Debian 10 Linux:

    postgres=# select upper('é' collate "C"), upper('é' collate "C.UTF-8");
     upper | upper 
    -------+-------
     é     | É
    (1 row)
    
    postgres=# select ('A' < E'\u0378' collate "C"),
                      ('A' < E'\u0378' collate "C.UTF-8");
     ?column? | ?column? 
    ----------+----------
     t        | f
    (1 row)
    

    (U+0378 não corresponde a nenhum caractere válido em Unicode).

    Outro exemplo com um caractere Unicode válido (o lado esquerdo é 'THUMBS UP SIGN' U+1F44D ):

    => select '?' < 'A' collate "C";
     ?column? 
    ----------
     f
    (1 row)
    
    => select '?' < 'A' collate "C.UTF-8";
     ?column? 
    ----------
     t
    (1 row)
    

    Quando lc_collatefor "C" (ou "POSIX"), a comparação é feita internamente pelo PostgreSQL. Nesse caso, ele compara as representações de bytes das strings usando memcmp.

    Nos demais casos em que libc é o provedor ( collprovider='c'em pg_collation), a comparação é feita pela strcoll_lbiblioteca C, então o próprio PostgreSQL não é responsável pelo resultado e, como mostram os contra-exemplos acima, não há razão para acreditar que será idêntico.

    Isso é verdade pelo menos para agrupamentos apoiados por libc. A partir da versão 10 do Postgres, os agrupamentos ICU podem ser usados. Esses agrupamentos são consistentes em todos os sistemas operacionais.

    Os detalhes sangrentos podem ser encontrados no código-fonte em backend/utils/adtvarlena.c , especialmente a varstrmp_cmpfunção.

    • 8
  3. Michael Hooreman
    2019-06-20T06:48:36+08:002019-06-20T06:48:36+08:00

    Na documentação do postgresql, https://www.postgresql.org/docs/11/collation.html :

    23.2.2.1. Agrupamentos padrão

    Em todas as plataformas, os agrupamentos denominados default, C e POSIX estão disponíveis. Agrupamentos adicionais podem estar disponíveis dependendo do suporte do sistema operacional. A ordenação padrão seleciona os valores LC_COLLATE e LC_CTYPE especificados no momento da criação do banco de dados. Os agrupamentos C e POSIX especificam o comportamento “C tradicional”, no qual apenas as letras ASCII de “A” a “Z” são tratadas como letras, e a classificação é feita estritamente por valores de byte de código de caractere.

    Além disso, o nome de agrupamento padrão SQL ucs_basic está disponível para codificação UTF8. É equivalente a C e classifica por ponto de código Unicode.

    Então, se meu entendimento estiver correto, C é ASCII, não UTF8.

    • 1

relate perguntas

  • Posso ativar o PITR depois que o banco de dados foi usado

  • Práticas recomendadas para executar a replicação atrasada do deslocamento de tempo

  • Os procedimentos armazenados impedem a injeção de SQL?

  • Sequências Biológicas do UniProt no PostgreSQL

  • Qual é a diferença entre a replicação do PostgreSQL 9.0 e o Slony-I?

Sidebar

Stats

  • Perguntas 205573
  • respostas 270741
  • best respostas 135370
  • utilizador 68524
  • Highest score
  • respostas
  • Marko Smith

    conectar ao servidor PostgreSQL: FATAL: nenhuma entrada pg_hba.conf para o host

    • 12 respostas
  • Marko Smith

    Como fazer a saída do sqlplus aparecer em uma linha?

    • 3 respostas
  • Marko Smith

    Selecione qual tem data máxima ou data mais recente

    • 3 respostas
  • Marko Smith

    Como faço para listar todos os esquemas no PostgreSQL?

    • 4 respostas
  • Marko Smith

    Listar todas as colunas de uma tabela especificada

    • 5 respostas
  • Marko Smith

    Como usar o sqlplus para se conectar a um banco de dados Oracle localizado em outro host sem modificar meu próprio tnsnames.ora

    • 4 respostas
  • Marko Smith

    Como você mysqldump tabela (s) específica (s)?

    • 4 respostas
  • Marko Smith

    Listar os privilégios do banco de dados usando o psql

    • 10 respostas
  • Marko Smith

    Como inserir valores em uma tabela de uma consulta de seleção no PostgreSQL?

    • 4 respostas
  • Marko Smith

    Como faço para listar todos os bancos de dados e tabelas usando o psql?

    • 7 respostas
  • Martin Hope
    Jin conectar ao servidor PostgreSQL: FATAL: nenhuma entrada pg_hba.conf para o host 2014-12-02 02:54:58 +0800 CST
  • Martin Hope
    Stéphane Como faço para listar todos os esquemas no PostgreSQL? 2013-04-16 11:19:16 +0800 CST
  • Martin Hope
    Mike Walsh Por que o log de transações continua crescendo ou fica sem espaço? 2012-12-05 18:11:22 +0800 CST
  • Martin Hope
    Stephane Rolland Listar todas as colunas de uma tabela especificada 2012-08-14 04:44:44 +0800 CST
  • Martin Hope
    haxney O MySQL pode realizar consultas razoavelmente em bilhões de linhas? 2012-07-03 11:36:13 +0800 CST
  • Martin Hope
    qazwsx Como posso monitorar o andamento de uma importação de um arquivo .sql grande? 2012-05-03 08:54:41 +0800 CST
  • Martin Hope
    markdorison Como você mysqldump tabela (s) específica (s)? 2011-12-17 12:39:37 +0800 CST
  • Martin Hope
    Jonas Como posso cronometrar consultas SQL usando psql? 2011-06-04 02:22:54 +0800 CST
  • Martin Hope
    Jonas Como inserir valores em uma tabela de uma consulta de seleção no PostgreSQL? 2011-05-28 00:33:05 +0800 CST
  • Martin Hope
    Jonas Como faço para listar todos os bancos de dados e tabelas usando o psql? 2011-02-18 00:45:49 +0800 CST

Hot tag

sql-server mysql postgresql sql-server-2014 sql-server-2016 oracle sql-server-2008 database-design query-performance sql-server-2017

Explore

  • Início
  • Perguntas
    • Recentes
    • Highest score
  • tag
  • help

Footer

AskOverflow.Dev

About Us

  • About Us
  • Contact Us

Legal Stuff

  • Privacy Policy

Language

  • Pt
  • Server
  • Unix

© 2023 AskOverflow.DEV All Rights Reserve