As codificações de caracteres além de UTF-8 (e talvez UTF-16 / UTF-32) devem ser descontinuadas?


31

Uma mina de estimação está olhando para tantos projetos de software que possuem montanhas de código para suporte a conjuntos de caracteres. Não me interpretem mal, sou a favor da compatibilidade e fico feliz que os editores de texto permitam abrir e salvar arquivos em vários conjuntos de caracteres. O que me incomoda é como a proliferação de codificações de caracteres não universais é rotulada como "suporte adequado a Unicode" em vez de "um problema".

Por exemplo, deixe-me escolher o PostgreSQL e seu suporte ao conjunto de caracteres . O PostgreSQL lida com dois tipos de codificação:

  • Codificação do cliente: usada na comunicação entre o cliente e o servidor.
  • Codificação do servidor: usada para armazenar texto internamente no banco de dados.

Entendo por que é bom dar suporte a muitas codificações de clientes. Permite que os clientes que não operam no UTF-8 se comuniquem com o PostgreSQL sem precisar realizar a conversão. O que não entendo é: por que o PostgreSQL suporta várias codificações de servidor ? Os arquivos de banco de dados são (quase sempre) incompatíveis de uma versão do PostgreSQL para a próxima, portanto, a compatibilidade entre versões não é o problema aqui.

UTF-8 é o único conjunto de caracteres padrão compatível com ASCII que pode codificar todos os pontos de código Unicode (se estiver errado, avise-me). Estou no campo em que UTF-8 é o melhor conjunto de caracteres, mas estou disposto a tolerar outros conjuntos universais de caracteres, como UTF-16 e UTF-32.

Acredito que todos os conjuntos de caracteres não universais devem ser descontinuados. Existe alguma razão convincente que eles não deveriam?


4
@ mario: A definição original de UTF-8 permitia até 6 bytes. Mais tarde, foi artificialmente restrito a cobrir apenas os caracteres que o UTF-16 poderia suportar.
precisa saber é

6
Pelo menos o PostgreSQL lida deliberadamente com múltiplas codificações de caracteres. É chato ter que lidar com uma mistura aleatória de UTF-8 e windows-1252 porque alguém simplesmente não se importava.
dan04

5
@ dan04: Trabalhar com textos em russo costumava ser uma dor, pois usavam várias codificações que eram substancialmente diferentes e geralmente usurpavam as coisas para trabalhar usando fontes diferentes (que geralmente mentem sobre a codificação em uso em seus metadados). Em suma, uma bagunça horrível. Eu suspeito que eles tenham limpado - provavelmente mudando para o UTF-8 - porque o número de solicitações de suporte dessa direção caiu imediatamente.
Donal Fellows

3
O intervalo Unicode teórico é de 0 a 0x10ffff. Nada mais. É o que diz o padrão Unicode. UTF-8 lida com todo o Unicode e sempre será. Ele não cobre o intervalo hipotético de uma codificação que não é Unicode, mas abrange todo o Unicode.
precisa saber é o seguinte

Respostas:


16

Como você mencionou o PostgreSQL, posso dizer com alguma autoridade que a principal razão pela qual as codificações não UTF8 do lado do servidor são suportadas com tantos detalhes é que os japoneses precisam dela. Aparentemente, nem sempre é possível uma conversão de ida e volta entre Unicode e as várias codificações "legadas" japonesas e, em alguns casos, as tabelas de conversão são até diferentes entre os fornecedores. É realmente desconcertante, mas aparentemente é assim. (O amplo suporte ao conjunto de caracteres também é um dos motivos pelos quais o PostgreSQL é tão popular no Japão.)

Como estamos falando de um sistema de banco de dados, uma das principais tarefas é poder armazenar e recuperar dados de forma confiável, conforme definido pelo usuário, para que a conversão do conjunto de caracteres com perdas às vezes não seja executada. Se você estava lidando com um navegador da web, digamos, onde tudo o que realmente importa é se o resultado parece bom, provavelmente você pode se dar bem com menos codificações, mas em um sistema de banco de dados você tem requisitos extras.

Algumas das outras razões mencionadas em outras respostas também se aplicam como argumentos de apoio. Mas enquanto os japoneses o vetarem, o suporte à configuração de caracteres não poderá ser reduzido.


Então, por causa dessas codificações, a conversão de texto em UTF-8 e vice-versa é perdida em geral? Mesmo se a conversão de volta for feita imediatamente (em vez de seis meses a partir de agora)?
Joey Adams

Joey Adams: Aparentemente sim.
Peter Eisentraut

3
Google para "unificação Han" para ver o porquê
Petr Viktorin 08/12/11

7

Duas razões óbvias: dependendo dos dados que você está armazenando, a conversão para um formato diferente pode levar bastante tempo e espaço extra. Se você estiver armazenando 400 megabytes de informações, dobrar os requisitos de armazenamento não é grande coisa - mas se você estiver armazenando 400 terabytes, isso começará a significar um pouco mais. A conversão de 400 terabytes de dados de (digamos) Shift-JIS para UTF-x também pode demorar um pouco.

Isso se torna especialmente difícil se você tiver (por exemplo) garantias de tempo de atividade que digam que o banco de dados estará disponível para todos, mas, digamos, 10 minutos em um determinado ano e você tiver um banco de dados que esteja sendo atualizado várias centenas de vezes por segundo. Mente-lhe, ainda é possível para gerenciar grandes conversões em tal situação um, mas é não algo a ser considerado fácil. Em alguns casos, pode facilmente levar anos de planejamento para se preparar para essa conversão.

Se você estava começando com um banco de dados que (por exemplo) apenas suportava ASCII, pode haver um bom motivo para debater se fazia sentido adicionar suporte a todas essas codificações - mas se você já as suporta, há pouco a ganhar com a eliminação suporte para eles.

Observe, em particular, que você provavelmente ganharia quase nada na maneira de simplificar o código, ou algo assim. Eles ainda precisariam de todas as rotinas de conversão para lidar com as conversões entre cliente e servidor de qualquer maneira. Dessa forma, descartar o suporte significaria descartar uma (menor) chamada de função nos caminhos "gravar no disco" e "ler do disco", mas pouco (se houver algo mais). Se você suportasse até duas codificações no disco, nem conseguiria isso - você ainda teria a chamada de função lá, então tudo o que faria seria restringir o intervalo de codificações suportadas por essa função.

Pelo menos, se eu estivesse projetando isso, provavelmente escreveria o núcleo do banco de dados para funcionar no UCS-4 e, em seguida, teria rotinas de conversão entre o núcleo e o disco e entre o núcleo e o usuário. Eu usaria o mesmo conjunto de rotinas nos dois casos, portanto, a rota mais simples seria permitir que o armazenamento em disco usasse exatamente o mesmo conjunto de codificações que os clientes tinham permissão para usar.


1
O Shift-JIS não é sincronizado automaticamente, o que torna a pesquisa complicada. Você obteria uma simplificação significativa se não a suportasse.
precisa saber é

@ dan04: se você já possui rotinas de pesquisa / indexação comprovadas no tempo para o Shift-JIS, mudar para UTF-8 ou até UCS2 provavelmente melhoraria o desempenho de forma insignificante. Para um novo banco de dados, você pode escolher uma codificação melhor, mais conveniente e regular, como UCS2 ou UTF-16.
9000

@ dan04: se você pudesse se safar sem apoiá-lo, ganharia um pouco. Contanto que você apoiá-lo vindo / indo para clientes, você vai ser preso com a maioria de sua feiúra ...
Jerry Coffin

5

Existem alguns problemas com o armazenamento apenas de UTF-8 no servidor:

  1. Qual é o limite de uma VARCHAR(20)coluna? São 20 bytes ou 20 "caracteres" (e em Unicode, o que é um "caractere" quando você leva em consideração a combinação de caracteres, ligaduras etc.)? Pior, e CHAR(20)onde ele realmente tem que reservar todo o espaço possível: eu acredito no MySQL, ele reserva 4 vezes o número de bytes para uma coluna codificada em UTF-8 (portanto, 80 bytes para CHAR(20)) apenas para lidar com o pior caso.
  2. Você precisa realizar conversões constantes de codificação entre a codificação do servidor e a codificação do cliente. Você pode argumentar que deseja parar de oferecer suporte a várias codificações de clientes também, mas, a menos que você faça isso, todas as strings precisam ser convertidas o tempo todo. Se você puder corresponder à codificação do servidor e do cliente, as conversões não serão necessárias.
  3. Como outros já apontaram, o UTF-8 é bastante eficiente para armazenar texto em inglês, mas é muito ineficiente para outros idiomas - idiomas do leste asiático, em particular. Você poderia permitir o uso de UTF-16 ou UTF-8 como naipes, suponho. Ou comprima o texto, mas isso torna a indexação e a pesquisa ineficientes.

Dito tudo isso, concordo com você: as codificações herdadas são praticamente inúteis e o Unicode geralmente é a melhor codificação para todos os novos aplicativos. Se eu estivesse escrevendo um servidor de banco de dados do zero hoje, suportaria apenas Unicode e não suportaria nenhuma codificação herdada.

A diferença é que o PostgreSQL e a maioria dos outros servidores de banco de dados em uso hoje existiam antes do Unicode ser uma opção viável. Portanto, eles já tinham suporte para codificações legadas (elas não eram legadas na época, é claro) e não há muito sentido extrair todo esse código por razões amplamente ideológicas.


10
"mas é muito ineficiente para outras línguas - línguas do leste asiático, em particular" Mesmo na prática? Considere esta página da Wikipedia em chinês . Embora exiba muitos caracteres chineses, na origem da página, os caracteres ASCII os sobrecarregam quase 7: 1.
Joey Adams

2
Se o N na coluna CHAR (N) fizer parte de um formato de identificador bem definido (por exemplo, um VIN é definido com exatamente 17 caracteres), provavelmente não será necessário combinar caracteres ou ligaduras. Caso contrário, N é apenas um limite arbitrário, que deve ser interpretado generosamente para evitar truncar dados.
dan04

5
@ Joey Adams: isso é verdade em HTML e XML, onde a marcação em si constitui uma grande proporção do texto (e é por isso que acho que o UTF-8 é uma boa escolha para a web), mas em um banco de dados você não costuma armazenar HTML. No final do dia, é apenas um fator de diferença de dois (ou menos), o que não é realmente muito.
Dean Harding

5
O ponto 2 desta resposta é irrelevante: aplica-se se o Unicode é ou não usado. O ponto 3 da bala exagera absolutamente a ineficiência e seu escopo. Ao mesmo tempo, essa resposta subestima amplamente os problemas causados ​​pelas codificações herdadas. É fácil presumir que o problema não é tão importante se tudo que você usa na vida é inglês.
Timwi

2
@ Dean: Eu não sabia que não era permitido comentar uma resposta sem postar uma das minhas.
Timwi 31/01

3

Codificações não universais (e especificamente de byte único) têm seu lugar: Em sistemas que:

  • Não possui memória suficiente para armazenar o banco de dados de caracteres Unicode.
  • Tenha uma fonte de byte único codificada na ROM.
  • Não tem acesso à Internet para fornecer uma fonte de arquivos codificados de maneira diferente.

Isso é verdade hoje para alguns tipos de dispositivos incorporados. Mas na área de trabalho e na sala do servidor, as codificações não-Unicode devem estar obsoletas há muito tempo .


3
Eu costumava ter computadores domésticos assim. Eu me livrei da maioria deles no início dos anos 80.
precisa

2

O UTF-8 é o melhor para você 1 egocêntrico falante de inglês. Se você fosse japonês, cerca de 99% de seus caracteres levariam de 3 a 4 bytes em vez de dois em UTF-16.

Dialetos não latinos realmente sofrem de UTF-8 no nível de tamanho. Não esqueça que, dentro de alguns anos, a maioria dos seus clientes poderá ser chinesa, e a escrita chinesa terá milhões de caracteres. Você não pode sustentar isso de forma eficiente com o UTF-8.

Caso contrário, eu odeio quando tenho documentos de texto que não estão em UTF - algo assim . Muitas vezes, saio do meu caminho se precisar ter a codificação adequada. No meu livro, as codificações não Unicode estão mortas.

1. Não leve a parte egocêntrica para o lado pessoal. Eu queria fazer uma ilustração colorida e realmente não quero dizer isso.


3
@ Matthew - 4x é claramente 4 vezes maior que x (para x positivo). Não vejo como a notação assintótica é relevante aqui. Eu nunca vi um disco rígido anunciado com uma taxa de crescimento assintótica. Normalmente, o tamanho permanece o mesmo durante toda a vida útil da unidade.
precisa saber é o seguinte

3
Milhões de caracteres não cabem no Unicode de qualquer maneira. Segundo o artigo da Wikipedia, atualmente existem cerca de sessenta mil caracteres Han. Como o Unicode não é apenas chinês, isso significa que um número razoável de caracteres chineses terá quatro bytes em UTF-16, o que é o máximo que o UTF-8 recebe atualmente. Seria interessante ver estatísticas sobre comprimentos de textos em chinês em UTF-8 e UTF-16.
David Thornley

6
@ David:> 99% de toda a escrita japonesa e chinesa usa caracteres que requerem apenas 2 bytes em UTF-16 e 3 em UTF-8. Os personagens que exigem mais são muito raros e / ou históricos.
Timwi

8
Lembre-se de que japonês e chinês geralmente usam menos caracteres por palavra. Trabalho com um aplicativo que possui grandes arquivos de idioma em inglês, japonês e chinês, todos codificados em utf-8. O arquivo chinês é realmente o menor, enquanto o arquivo japonês é cerca de 15% maior que o original em inglês.
Gort the Robot

3
Absurdo. Qualquer coisa que use dois bytes em UTF-16 não terá mais que 3 bytes em UTF-8. Qualquer coisa com quatro bytes em UTF-8 é de 4 bytes em UTF-16. Não existem "milhões" de caracteres chineses e, obviamente, eles não caberiam em 16 bits.
precisa saber é o seguinte

1

O Unicode está fundamentalmente quebrado e é improvável que algum dia tenha sido corrigido. Ele precisa ser substituído por algo melhor, algo verdadeiramente universal. Se algo precisa ser preterido, é Unicode.

Exemplos de problemas com o Unicide:

  • UTF8 é um hack razoável, mas a maioria dos softwares baseados em UTF16 está corrompida. A maioria dos aplicativos Windows compatíveis com Unicode usa UTF16, incluindo o próprio SO. O problema mais comum é não suportar mais do que o plano básico, ou seja, caracteres com várias palavras.

  • A unificação de Han é um desastre absoluto. É impossível misturar texto em japonês / chinês / coreano em um único documento sem metadados extras e difícil detectar qual fonte deve ser usada.

  • Caracteres combinacionais são outro desastre. Esquemas de codificação mais sensíveis mapeiam um caractere para um código, o que torna as seqüências de processamento relativamente sãs. Unicode não. O Unicode nem é consistente - os caracteres Han são principalmente combinações, mas não são codificados como tal, onde estão os caracteres combinacionais europeus.

  • Os nomes de algumas pessoas não podem ser escritos corretamente em Unicode ou são altamente propensos a serem renderizados incorretamente devido aos problemas mencionados acima. Isso pode ter graves consequências, por exemplo, ao tentar embarcar em uma aeronave com um passaporte que não corresponde ao que está (incorretamente) impresso no bilhete.

Devido a esses problemas e muito mais, muitos softwares que não são do inglês não podem usar Unicode e dependem de codificações de caracteres locais. Isso é particularmente comum no software japonês e chinês.

Idealmente, o Unicode deve ser preterido. A codificação de caracteres TRON é um substituto muito bom para Unicode e amplamente compatível com o software existente que não será atualizado.


Sua alegação de que é impossível misturar as diferentes variantes de caracteres (japonês / coreano / chinês) parece estar desatualizada há 15 anos, o padrão Unicode 3.2 em 2002. O Unicode suporta seletores de variação, pontos de código que após um ponto de código han especificam explicitamente qual forma deve ser exibido. Além disso, os caracteres combinatórios são especificados como "combinando marcas diacríticas" com caracteres base (a °) e glifos especiais (å), o processo de convertê-los vice-versa é "normalização". Portanto, não, o Unicode não é fundamentalmente quebrado.
21818 Thorsten S.

Você ilustra muitas das falhas. Alguns idiomas usam caracteres combinacionais, outros não, e o Unicode não pode decidir qual prefere. Como indiquei, a maioria dos softwares que afirmam suportar o Unicode não entende esses problemas de qualquer maneira e o exibirá errado, mesmo com os seletores. Os programadores não devem ser especialistas em idiomas, que é a outra falha fundamental no Unicode.
usuário

0

Talvez por escrever, mas não por ler.

Existe muito conteúdo existente que usa essas codificações, e algumas como base64 não estão indo a lugar algum, porque alguns protocolos de texto exigem isso como forma de incorporar dados binários.

Um problema real é a detecção automática de codificações, o que leva a falhas de segurança. Eu não me importaria de ver algumas codificações obscuras como UTF-7 simplesmente desaparecerem.

A detecção automática também tende a lidar mal com o conteúdo produzido pela concatenação ingênua de cadeias de bytes.


7
Base64 não é uma codificação de caracteres.
precisa saber é

0

Posso concordar que a codificação de caracteres padrão para bancos de dados e novos aplicativos deve ser algum tipo de variante UTF. Eu pessoalmente optaria pelo UTF-16, pois parece ser uma troca razoável de espaço e complexidade (mais do que o UTF-8). Dito isto, algumas codificações de caracteres ainda fazem sentido em certos casos.

  • Se você estiver armazenando / transferindo texto base64, precisará apenas de ASCII e poderá até mesmo usar protocolos codificados de 7 bits, como email. A sobrecarga extra do UTF-8 é desnecessária.
  • Vários arquivos e dados existentes são criados nessas codificações de caracteres mais antigas, sendo importante lê-las.

Observe que existem 4 algoritmos de normalização UTF padrão. Se você estiver preocupado com caracteres com vários pontos de código, poderá usar um dos dois algoritmos de normalização que os juntam no caractere de ponto único equivalente. A diferença entre eles tem a ver com equivalência lógica vs. equivalência física de caracteres.


1
Os votantes negativos podem dizer por que votaram abaixo?
Berin Loritsch 28/01

3
Não diminuí o voto, mas o objetivo principal da base64 é transferir dados binários por um canal de texto. Se você pudesse escolher qual codificação usar nesse canal, não usaria uma codificação de texto. Mesmo que seu canal seja realmente ASCII simples, a base 64 está usando apenas 6 dos 7 bits - uma sobrecarga significativa já.
31311 Steve1314

Espero que alguém não tenha lido apenas os pontos da bala. Essas foram as exceções ao uso de UTF. E você está incorreto sobre a base 64 usando apenas 6 de 8 bytes. O primeiro conjunto de "caracteres" ASCII são caracteres de controle não imprimíveis, o que força alguns caracteres na base64 a usar 7 dos 8 bytes. Evita propositadamente o bit alto, porque todos esses caracteres não existem em todas as páginas de códigos, enquanto os caracteres de 0 a 127 são.
Berin Loritsch

2
@Berin - (1) não, mas esse "concordo" não é muito sem os pontos de bala e (2) a base 64 tem 64 "dígitos". 64 dígitos vale 6 bits, porque 2 ^ 6 == 64. Como você representa isso em um espaço de código de 7 bits (ou 8 bits, ou mesmo 8 bytes, se necessário) é separado da quantidade de dados realmente existente. Evitar os caracteres não imprimíveis, etc., é o motivo da sobrecarga - isso não significa que a sobrecarga não exista. Escolha um canal projetado para dados binários e essa sobrecarga não existe.
31311 Steve114

3
Lembre-se de que a base64 foi inventada para lidar com o envio de dados binários por um canal somente de texto. É conhecido por ser ineficiente (expansão 3: 4), mas lida com limitações técnicas em certas opções de transporte. O legado seria o email e os fóruns da UseNet, mas um aplicativo mais moderno seria incorporar dados binários em XML. Às vezes, o canal adequado não existe e você precisa trabalhar com as limitações dos existentes.
Berin Loritsch
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.