¿Cuál es la diferencia entre utf8_general_ci y utf8_unicode_ci?

Entre utf8_general_ci y utf8_unicode_ci, ¿hay alguna diferencia en términos de rendimiento?

Solución

Estas dos colaciones son ambas para la codificación de caracteres UTF-8. Las diferencias están en cómo se ordena y compara el texto. Nota: Debe utilizar utf8mb4 en lugar de utf8. Ambos se refieren a la codificación UTF-8, pero el antiguo utf8 tenía una limitación específica de MySQL que impedía el uso de caracteres numerados por encima de 0xFFFD. *Nota: Las nuevas versiones de MySQL han actualizado las reglas de ordenación de Unicode, disponibles bajo nombres como utf8mb4_0900_ci para las reglas basadas en Unicode 9.0 - y sin una variante general equivalente. **Principales diferencias

  • El código utf8mb4_unicode_ci se basa en las reglas oficiales de Unicode para la clasificación y comparación universal, que clasifica con precisión en una amplia gama de idiomas.
  • utf8mb4_general_ci es un conjunto simplificado de reglas de ordenación que pretende hacerlo tan bien como sea posible mientras toma muchos atajos diseñados para mejorar la velocidad. No sigue las reglas de Unicode y dará lugar a una ordenación o comparación no deseada en algunas situaciones, como cuando se utilizan determinados idiomas o caracteres. En los servidores modernos, este aumento de rendimiento será casi insignificante. Se ideó en una época en la que los servidores tenían una fracción mínima del rendimiento de la CPU de los ordenadores actuales. Nota: ahora existe una versión actualizada de utf8mb4_unicode_ci llamada utf8mb4_0900_ai_ci - esta se basa en los cambios de la versión 9.0 de Unicode, y también es aparentemente más rápida. Adopta un nuevo esquema de nomenclatura en el que 0900 es la versión de Unicode y ai significa insensible a los acentos - al igual que el anterior utf8mb4_unicode_ci, los acentos en las letras no se consideran significativos. Ventajas de utf8mb4_unicode_ci con respecto a utf8mb4_general_ci. utf8mb4_unicode_ci, que utiliza las reglas de Unicode para la ordenación y la comparación, emplea un algoritmo bastante complejo para la ordenación correcta en una amplia gama de idiomas y cuando se utiliza una amplia gama de caracteres especiales. Estas reglas deben tener en cuenta las convenciones específicas de cada idioma; no todo el mundo ordena sus caracteres en lo que llamaríamos "orden alfabético". En lo que respecta a los idiomas latinos (es decir, "europeos"), no hay mucha diferencia entre la ordenación Unicode y la ordenación simplificada utf8mb4_general_ci de MySQL, pero todavía hay algunas diferencias:
  • Por ejemplo, la ordenación Unicode ordena la "ß" como "ss", y la "Œ" como "OE" como la gente que usa esos caracteres normalmente querría, mientras que utf8mb4_general_ci los ordena como caracteres individuales (presumiblemente como "s" y "e" respectivamente).
  • Algunos caracteres Unicode se definen como ignorables, lo que significa que no deberían contar en el orden de clasificación y la comparación debería pasar al siguiente carácter. utf8mb4_unicode_ci los maneja adecuadamente. En idiomas no latinos, como los asiáticos o los que tienen alfabetos diferentes, puede haber muchas más diferencias entre la ordenación Unicode y la ordenación simplificada de utf8mb4_general_ci. La idoneidad de utf8mb4_general_ci dependerá en gran medida del idioma utilizado. Para algunos lenguajes, será bastante inadecuado. ¿Qué deberías usar? Es casi seguro que no hay razón para usar utf8mb4_general_ci, ya que hemos dejado atrás el punto en el que la velocidad de la CPU es lo suficientemente baja como para que la diferencia de rendimiento sea importante. Su base de datos estará casi seguramente limitada por otros cuellos de botella que este. En el pasado, algunas personas recomendaban utilizar utf8mb4_general_ci excepto cuando la ordenación precisa iba a ser lo suficientemente importante como para justificar el coste de rendimiento. Hoy en día, ese coste de rendimiento prácticamente ha desaparecido, y los desarrolladores se toman más en serio la internacionalización. Se puede argumentar que si la velocidad es más importante que la precisión, es mejor no hacer ninguna ordenación. Es trivial hacer un algoritmo más rápido si no necesitas que sea preciso. Así que, utf8mb4_general_ci es un compromiso que probablemente no es necesario por razones de velocidad y probablemente tampoco es adecuado por razones de precisión. Otra cosa que añadiré es que, aunque sepas que tu aplicación sólo admite el idioma inglés, es posible que tenga que lidiar con los nombres de las personas, que a menudo pueden contener caracteres utilizados en otros idiomas en los que es igual de importante ordenar correctamente. Usar las reglas de Unicode para todo ayuda a añadir la tranquilidad de que la muy inteligente gente de Unicode ha trabajado muy duro para hacer que la ordenación funcione correctamente. Qué significan las partes* En primer lugar, ci es para la ordenación y comparación insensible a mayúsculas y minúsculas*. Esto significa que es adecuado para datos textuales, y que las mayúsculas y minúsculas no son importantes. Los otros tipos de cotejo son cs (sensible a mayúsculas y minúsculas) para datos textuales en los que las mayúsculas y minúsculas son importantes, y bin, para los casos en los que la codificación debe coincidir, bit a bit, lo que es adecuado para los campos que son realmente datos binarios codificados (incluyendo, por ejemplo, Base64). La ordenación sensible a mayúsculas y minúsculas conduce a algunos resultados extraños y la comparación sensible a mayúsculas y minúsculas puede dar lugar a valores duplicados que sólo difieren en las letras, por lo que las colaciones sensibles a mayúsculas y minúsculas están cayendo en desgracia para los datos textuales - si las mayúsculas y minúsculas son importantes para usted, entonces la puntuación ignorable y demás probablemente también sea importante, y una colación binaria podría ser más apropiada. A continuación, unicode o general se refiere a las reglas específicas de ordenación y comparación - en particular, la forma en que se normaliza o compara el texto. Hay muchos conjuntos de reglas diferentes para la codificación de caracteres utf8mb4, siendo unicode y general dos que intentan funcionar bien en todos los idiomas posibles en lugar de uno específico. Las diferencias entre estos dos conjuntos de reglas son el tema de esta respuesta. Tenga en cuenta que unicode utiliza las reglas de Unicode 4.0. Las versiones recientes de MySQL añaden los conjuntos de reglas unicode_520 que utilizan reglas de Unicode 5.2, y 0900 (eliminando la parte "unicode_") que utiliza reglas de Unicode 9.0. Y por último, utf8mb4 es, por supuesto, la codificación de caracteres utilizada internamente. En esta respuesta sólo hablo de codificaciones basadas en Unicode.
Comentarios (25)

Este post lo describe muy bien.

En resumen: utf8_unicode_ci utiliza el Algoritmo de Cotejo Unicode tal y como se define en los estándares Unicode, mientras que utf8_general_ci es una ordenación más simple que da lugar a resultados de ordenación "menos precisos".

Comentarios (5)

Consulte el manual de mysql, sección Juegos de caracteres Unicode:

Para cualquier conjunto de caracteres Unicode, las operaciones realizadas usando la cotejo _general_ci son más rápidas que aquellas para el cotejo _unicode_ci. Por ejemplo, las comparaciones para el utf8_general_ci collation son más rápidas, pero ligeramente menos correctas, que comparaciones para utf8_unicode_ci. La razón de esto es que utf8_unicode_ci soporta mapeos como como expansiones; es decir, cuando un carácter se compara como igual a combinaciones de otros caracteres. En ejemplo, en alemán y otros idiomas idiomas "ß" es igual a "ss". utf8_unicode_ci también admite contracciones y caracteres ignorables. utf8_general_ci es una compaginación heredada que no soporta expansiones, contracciones, o caracteres ignorables. Sólo puede hacer comparaciones uno a uno comparación entre caracteres.

Así que para resumir, utf_general_ci utiliza un conjunto de comparaciones más pequeño y menos correcto (según el estándar) que utf_unicode_ci que debería implementar todo el estándar. El conjunto de utf_general_ci será más rápido porque hay menos cálculos que hacer.

Comentarios (6)