UTF-8: Geral? Bin? Unicode

Estou tentando descobrir qual agrupamento devo usar para vários tipos de dados. 100% do conteúdo que vou armazenar é enviado pelo usuário.

Meu entendimento é que eu deveria estar usando CI geral UTF-8 (insensível a maiúsculas e minúsculas) em vez de Binário UTF-8. No entanto, não consigo encontrar uma distinção clara entre o CI Geral do UTF-8 e o CI Unicode UTF-8.

  1. Devo estar armazenando conteúdo enviado pelo usuário em colunas de CI Unicode UTF-8 General ou UTF-8?
  2. Que tipo de dados seria aplicável o Binário UTF-8?

Em geral, utf8_general_ci é mais rápido que utf8_unicode_ci , mas menos correto.

Aqui está a diferença:

Para qualquer conjunto de caracteres Unicode, as operações executadas usando o agrupamento _general_ci são mais rápidas que as do agrupamento _unicode_ci . Por exemplo, as comparações para o agrupamento utf8_general_ci são mais rápidas, mas um pouco menos corretas, do que as comparações para utf8_unicode_ci. A razão para isto é que o utf8_unicode_ci suporta mapeamentos como expansões; isto é, quando um caractere é comparado como igual a combinações de outros caracteres. Por exemplo, em alemão e algumas outras línguas, “ß” é igual a “ss”. utf8_unicode_ci também suporta contrações e caracteres ignoráveis. utf8_general_ci é um agrupamento herdado que não suporta expansões, contrações ou caracteres ignoráveis. Pode fazer apenas comparações de um para um entre os caracteres.

Citado de: http://dev.mysql.com/doc/refman/5.0/en/charset-unicode-sets.html

Para uma explicação mais detalhada, leia a seguinte postagem nos fóruns da MySQL: http://forums.mysql.com/read.php?103,187048,188748

Quanto ao utf8_bin: Tanto o utf8_general_ci quanto o utf8_unicode_ci realizam uma comparação sem distinção entre maiúsculas e minúsculas. Em constrast, utf8_bin faz distinção entre maiúsculas e minúsculas (entre outras diferenças), porque compara os valores binários dos caracteres.

Você também deve estar ciente do fato de que, com utf8_general_ci ao usar um campo varchar como índice exclusivo ou primário, inserir dois valores como ‘a’ e ‘á’ resultaria em um erro de chave duplicado.

  • utf8_bin compara os bits às cegas. Nenhum caso de dobramento, sem decapagem de acentuação.
  • utf8_general_ci compara um byte com um byte. Ele faz a dobra de dobragem e acentuação, mas não há comparações de dois caracteres: ij não é igual ij neste agrupamento.
  • utf8_*_ci é um conjunto de regras específicas do idioma, mas por outro lado, como unicode_ci . Alguns casos especiais: Ç , Č , ch , ll
  • utf8_unicode_ci segue um antigo padrão Unicode para comparações. ij = ij , mas ae ! = æ
  • utf8_unicode_520_ci segue um novo padrão Unicode. ae = æ

Veja o gráfico de agrupamento para detalhes sobre o que é igual ao que em vários agrupamentos utf8.

utf8 , conforme definido pelo MySQL, está limitado aos códigos utf8 de 1 a 3 bytes. Isso deixa de fora Emoji e alguns dos chineses. Então você deve realmente mudar para o utf8mb4 se você quiser ir muito além da Europa.

Os pontos acima aplicam-se ao utf8mb4 , após alteração ortográfica adequada. Indo adiante, utf8mb4 e utf8mb4_unicode_520_ci são preferidos.

  • utf16 e utf32 são variantes no utf8; praticamente não há utilidade para eles.
  • O ucs2 está mais próximo de “Unicode” do que de “utf8”; praticamente não há utilidade para isso.

Realmente, testei valores de salvamento como ‘é’ e ‘e’ na coluna com índice exclusivo e eles causam erros duplicados em ‘utf8_unicode_ci’ e ‘utf8_general_ci’. Você pode salvá-los somente na coluna agrupada ‘utf8_bin’.

E o mysql docs (em http://dev.mysql.com/doc/refman/5.7/en/charset-applications.html ) sugere em seu conjunto de exemplos o agrupamento ‘utf8_general_ci’.

 [mysqld] character-set-server=utf8 collation-server=utf8_general_ci