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?
993
3
Entre utf8_general_ci
e utf8_unicode_ci
, existem diferenças em termos de desempenho?
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 deutf8
. Ambos se referem à codificação UTF-8, mas o antigoutf8
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 comoutf8mb4_0900_ci
para regras baseadas no Unicode 9.0 - e sem a variantegeneral
equivalente. **Diferenças-chave***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 doutf8mb4_unicode_ci
chamadoutf8mb4_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 qual0900
é a versão Unicode eai
significa insensível a acentos - como o anteriorutf8mb4_unicode_ci
, acentos em letras não são considerados significativos. **Benefícios doutf8mb4_unicode_ci
sobre outf8mb4_general_ci
***. Outf8mb4_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 simplificadautf8mb4_general_ci
no MySQL, mas ainda há algumas diferenças:utf8mb4_general_ci
os ordena como caracteres únicos (presumivelmente como "s" e "e" respectivamente).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 simplificadautf8mb4_general_ci
. A adequação doutf8mb4_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 outf8mb4_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 doutf8mb4_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ãocs' (sensível a maiúsculas e minúsculas) para dados textuais onde o caso é importante, e
bin', 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
ougeneral
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 ounicode
e ogeneral
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 ounicode
utiliza regras do Unicode 4.0. Versões recentes do MySQL adicionam os conjuntos de regrasunicode_520
utilizando regras do Unicode 5.2, e0900
(descartando a parte "unicode_") utilizando regras do Unicode 9.0. E por último, outf8mb4
é, naturalmente, a codificação de caracteres utilizada internamente. Nesta resposta eu estou falando apenas de codificações baseadas em Unicode.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".
Veja a seção Unicode Character Sets do manual do mysql:
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.