Qual's a diferença entre utf8_general_ci e utf8_unicode_ci

Entre utf8_general_ci e utf8_unicode_ci, existem diferenças em termos de desempenho?

Solução

Estas duas colações são ambas para a codificação de caracteres UTF-8. As diferenças estão na forma como o texto é ordenado e comparado. Note: Você deve utilizar utf8mb4 ao invés de utf8. Ambos se referem à codificação UTF-8, mas o antigo utf8 tinha uma limitação específica do MySQL impedindo o uso de caracteres numerados acima de 0xFFFD. Note: Novas versões do MySQL possuem regras de ordenação Unicode atualizadas, disponíveis sob nomes como utf8mb4_0900_ci para regras baseadas no Unicode 9.0 - e sem a variante general equivalente. **Diferenças-chave***

  • 'utf8mb4_unicode_ci' é baseado nas regras oficiais Unicode para a classificação e comparação universal, que é classificado com precisão em uma grande variedade de idiomas.
  • utf8mb4_general_ci é um conjunto simplificado de regras de ordenação que visa fazer o melhor possível e, ao mesmo tempo, tomar muitos atalhos projetados para melhorar a velocidade. Ele não segue as regras Unicode e resultará em uma ordenação ou comparação indesejável em algumas situações, como quando se utiliza determinados idiomas ou caracteres. Em servidores modernos, este aumento de desempenho será praticamente insignificante. Foi concebido numa altura em que os servidores tinham uma pequena fracção do desempenho da CPU dos computadores actuais. Note: existe agora uma versão atualizada do utf8mb4_unicode_ci chamado utf8mb4_0900_ai_ci - isto é baseado em mudanças na versão Unicode 9.0, e é também aparentemente mais rápido. Ele adota um novo esquema de nomenclatura pelo qual 0900 é a versão Unicode e ai significa insensível a acentos - como o anterior utf8mb4_unicode_ci, acentos em letras não são considerados significativos. **Benefícios do utf8mb4_unicode_ci sobre o utf8mb4_general_ci***. O utf8mb4_unicode_ci, que utiliza as regras Unicode para ordenação e comparação, emprega um algoritmo bastante complexo para a ordenação correta em uma grande variedade de idiomas e quando se utiliza uma grande variedade de caracteres especiais. Essas regras precisam levar em conta as convenções específicas do idioma; nem todos ordenam seus caracteres no que chamaríamos de 'ordem alfabética'. No que diz respeito às línguas latinas (ou seja, "europeias"), não há muita diferença entre a ordenação Unicode e a ordenação simplificada utf8mb4_general_ci no MySQL, mas ainda há algumas diferenças:
  • Por exemplo, a ordenação Unicode ordena "ß" como "ss", e "Œ" como "OE" como as pessoas que utilizam esses caracteres normalmente gostariam, enquanto que o utf8mb4_general_ci os ordena como caracteres únicos (presumivelmente como "s" e "e" respectivamente).
  • Alguns caracteres Unicode são definidos como ignoráveis, o que significa que eles não devem contar para a ordem de ordenação e a comparação deve passar para o próximo caractere em vez disso. O utf8mb4_unicode_ci lida com eles corretamente. Em línguas não-latinas, como as asiáticas ou com alfabetos diferentes, pode haver muitas mais diferenças entre a ordenação Unicode e a ordenação simplificada utf8mb4_general_ci. A adequação do utf8mb4_general_ci dependerá muito do idioma utilizado. Para alguns idiomas, será bastante inadequada. O que você deve utilizar? Quase certamente não há mais razão para utilizar o utf8mb4_general_ci, pois deixamos para trás o ponto onde a velocidade da CPU é baixa o suficiente para que a diferença de desempenho seja importante. Sua base de dados será quase certamente limitada por outros gargalos que não este. No passado, algumas pessoas recomendaram a utilização do utf8mb4_general_ci exceto quando a ordenação precisa seria importante o suficiente para justificar o custo de performance. Hoje, esse custo de performance praticamente desapareceu, e os desenvolvedores estão tratando a internacionalização com mais seriedade. Há um argumento a ser feito de que se a velocidade é mais importante para você do que a precisão, você pode muito bem não fazer nenhuma ordenação. É trivial fazer um algoritmo mais rápido se você não precisar dele para ser preciso. Portanto, utf8mb4_general_ci é um compromisso que provavelmente não é necessário por razões de velocidade e provavelmente também não é adequado por razões de precisão. Uma outra coisa que vou acrescentar é que mesmo que você saiba que sua aplicação só suporta a língua inglesa, ela ainda pode precisar lidar com nomes de pessoas, que muitas vezes podem conter caracteres usados em outras línguas nas quais é igualmente importante classificar corretamente. Usar as regras Unicode para tudo ajuda a adicionar paz de espírito que as pessoas muito inteligentes do Unicode têm trabalhado muito duro para fazer a ordenação funcionar corretamente. **O que as partes significam** Em primeiro lugar, ci é para a classificação e comparação de casos insensíveis*. Isto significa que é adequado para dados textuais, e o caso não é importante. Os outros tipos de agrupamento são cs' (sensível a maiúsculas e minúsculas) para dados textuais onde o caso é importante, ebin', para onde a codificação precisa corresponder, bit a bit, que é adequado para campos que são realmente dados binários codificados (incluindo, por exemplo, Base64). A ordenação sensível a maiúsculas e minúsculas leva a alguns resultados estranhos e a comparação sensível a maiúsculas e minúsculas pode resultar em valores duplicados que diferem apenas em maiúsculas e minúsculas, de modo que as colações sensíveis a maiúsculas e minúsculas estão caindo fora do favor dos dados textuais - se maiúsculas e minúsculas forem significativas para você, então a pontuação ignorável e assim por diante provavelmente também é significativa, e uma colação binária pode ser mais apropriada. A seguir, unicode ou general refere-se às regras específicas de ordenação e comparação - em particular, a forma como o texto é normalizado ou comparado. Existem muitos conjuntos diferentes de regras para a codificação de caracteres utf8mb4, com o unicode e o general sendo dois que tentam funcionar bem em todos os idiomas possíveis ao invés de um específico. As diferenças entre estes dois conjuntos de regras são o assunto desta resposta. Note que o unicode utiliza regras do Unicode 4.0. Versões recentes do MySQL adicionam os conjuntos de regras unicode_520 utilizando regras do Unicode 5.2, e 0900 (descartando a parte "unicode_") utilizando regras do Unicode 9.0. E por último, o utf8mb4 é, naturalmente, a codificação de caracteres utilizada internamente. Nesta resposta eu estou falando apenas de codificações baseadas em Unicode.
Comentários (25)

Este post descreve-o muito bem.

Em resumo: utf8_unicode_ci usa o Algoritmo de Colação Unicode como definido nos padrões Unicode, enquanto utf8_general_ci é uma ordem de classificação mais simples que resulta em resultados de classificação "menos precisos".

Comentários (5)

Veja a seção Unicode Character Sets do manual do mysql:

Para qualquer conjunto de caracteres Unicode, operações realizadas utilizando o a colação _general_ci é mais rápida do que a colação do _unicode_ci. Por exemplo, as comparações para a utf8_general_ci collation são mais rápidos, mas ligeiramente menos correto, do que comparações para utf8_unicode_ci. O a razão para isto é que utf8_unicode_ci suporta mapeamentos tais como expansões; isto é, quando um personagem se compara como igual a combinações de outros caracteres. Para exemplo, em alemão e alguns outros línguas "ß" é igual a "ss". utf8_unicode_ci também suporta contracções e caracteres ignoráveis. utf8_general_ci é uma colação de legado que não suporta expansões, contracções, ou caracteres ignoráveis. só pode fazer um-para-um comparações entre personagens.

Assim, para resumir, utf_general_ci usa um conjunto menor e menos correto (de acordo com o padrão) de comparações do que utf_unicode_ci que deveria implementar o padrão inteiro. O conjunto general_ci será mais rápido porque há menos computações a fazer.

Comentários (6)