Saltar al contenido

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

Indagamos por diferentes foros y así darte la solución para tu inquietud, si tienes alguna inquietud puedes dejarnos la duda y respondemos con gusto, porque estamos para ayudarte.

Solución:

Para aquellas personas que todavía llegan a esta pregunta en 2020 o más tarde, hay opciones más nuevas que pueden ser mejores que ambos de estos. Por ejemplo, utf8mb4_0900_ai_ci.

Todas estas intercalaciones son para la codificación de caracteres UTF-8. Las diferencias están en cómo se ordena y compara el texto.

_unicode_ci y _general_ci Hay dos conjuntos de reglas diferentes para clasificar y comparar texto de la forma que esperamos. Las versiones más recientes de MySQL también introducen nuevos conjuntos de reglas, como _0900_ai_ci para reglas equivalentes basadas en Unicode 9.0 – y sin equivalente _general_ci variante. Las personas que lean esto ahora probablemente deberían usar una de estas intercalaciones más nuevas en lugar de _unicode_ci o _general_ci. La descripción de esas colaciones más antiguas a continuación se proporciona solo con fines de interés.

MySQL se encuentra actualmente en transición de una implementación UTF-8 defectuosa y antigua. Por ahora, necesitas usar utf8mb4 en lugar de utf8 para la parte de codificación de caracteres, para asegurarse de que está obteniendo la versión fija. La versión defectuosa permanece por compatibilidad con versiones anteriores, aunque está en desuso.

Diferencias clave

  • utf8mb4_unicode_ci se basa en las reglas oficiales de Unicode para la clasificación y comparación universales, que clasifica con precisión en una amplia gama de idiomas.

  • utf8mb4_general_ci es un conjunto simplificado de reglas de clasificación que tiene como objetivo hacerlo lo mejor que puede mientras toma muchos atajos diseñados para mejorar la velocidad. No sigue las reglas Unicode y dará como resultado una clasificación o comparación no deseadas en algunas situaciones, como cuando se usan idiomas o caracteres particulares.

    En los servidores modernos, este aumento de rendimiento será casi insignificante. Fue ideado en una época en la que los servidores tenían una pequeña fracción del rendimiento de la CPU de las computadoras actuales.

Beneficios de utf8mb4_unicode_ci sobre utf8mb4_general_ci

utf8mb4_unicode_ci, que usa las reglas Unicode para ordenar y comparar, emplea un algoritmo bastante complejo para ordenar correctamente en una amplia gama de idiomas y cuando usa una amplia gama de caracteres especiales. Estas reglas deben tener en cuenta las convenciones específicas del idioma; no todo el mundo clasifica a sus personajes en lo que llamaríamos “orden alfabético”.

En lo que respecta a los idiomas latinos (es decir, “europeos”), no hay mucha diferencia entre el ordenamiento Unicode y el simplificado utf8mb4_general_ci ordenar en MySQL, pero todavía hay algunas diferencias:

  • Por ejemplo, la intercalación Unicode clasifica “ß” como “ss” y “Œ” como “OE” como las personas que usan esos caracteres normalmente querrían, mientras que utf8mb4_general_ci los clasifica como caracteres individuales (presumiblemente como “s” y “e” respectivamente).

  • Algunos caracteres Unicode se definen como ignorables, lo que significa que no deben contar para el orden de clasificación y la comparación debe pasar al siguiente carácter. utf8mb4_unicode_ci maneja estos correctamente.

En idiomas no latinos, como idiomas asiáticos o idiomas con alfabetos diferentes, puede haber muchos más diferencias entre la ordenación Unicode y la simplificada utf8mb4_general_ci clasificación. La idoneidad de utf8mb4_general_ci Dependerá en gran medida del idioma utilizado. Para algunos idiomas, 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 donde la velocidad de la CPU es lo suficientemente baja como para que la diferencia de rendimiento sea importante. Es casi seguro que su base de datos estará limitada por otros cuellos de botella además de este.

En el pasado, algunas personas recomendaban usar utf8mb4_general_ci excepto cuando una clasificación precisa iba a ser lo suficientemente importante como para justificar el costo de rendimiento. Hoy en día, ese costo de rendimiento prácticamente ha desaparecido y los desarrolladores están tratando la internacionalización con más seriedad.

Se puede argumentar que si la velocidad es más importante para usted que la precisión, es mejor que no haga ninguna clasificación. Es trivial hacer un algoritmo más rápido si no necesita que sea preciso. Entonces, utf8mb4_general_ci es un compromiso que probablemente no sea necesario por razones de velocidad y probablemente tampoco sea adecuado por razones de precisión.

Otra cosa que agregaré es que incluso si sabe que su aplicación solo es compatible con el idioma inglés, es posible que deba lidiar con los nombres de las personas, que a menudo pueden contener caracteres utilizados en otros idiomas en los que es igualmente importante ordenarlos correctamente. . El uso de las reglas Unicode para todo ayuda a tener la tranquilidad de que la gente inteligente de Unicode ha trabajado muy duro para que la clasificación funcione correctamente.

Que significan las partes

Primeramente, ci es para no distingue entre mayúsculas y minúsculas clasificación y comparación. Esto significa que es adecuado para datos textuales y el uso de mayúsculas y minúsculas no es importante. Los otros tipos de colación son cs (distingue entre mayúsculas y minúsculas) para datos textuales donde las mayúsculas y minúsculas son importantes, y bin, para donde la codificación debe coincidir, bit por bit, lo cual es adecuado para campos que son realmente datos binarios codificados (incluyendo, por ejemplo, Base64). La clasificación que distingue entre mayúsculas y minúsculas conduce a algunos resultados extraños y la comparación entre mayúsculas y minúsculas puede dar como resultado valores duplicados que difieren solo en mayúsculas y minúsculas, por lo que las intercalaciones que distinguen entre mayúsculas y minúsculas están cayendo en desgracia para los datos textuales; si el caso es importante para usted, entonces, la puntuación es ignorable. y así sucesivamente probablemente también sea significativo, y una intercalación binaria podría ser más apropiada.

Próximo, unicode o general se refiere a las reglas específicas de clasificació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, con unicode y general siendo 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 reglas de Unicode 4.0. Las versiones recientes de MySQL agregan los conjuntos de reglas unicode_520 usando reglas de Unicode 5.2, y 0900 (eliminando la parte “unicode_”) usando reglas de Unicode 9.0.

Y por último, utf8mb4 es, por supuesto, la codificación de caracteres utilizada internamente. En esta respuesta, estoy hablando solo de codificaciones basadas en Unicode.

Quería saber cuál es la diferencia de rendimiento entre usar utf8_general_ci y utf8_unicode_ci, pero no encontré ningún punto de referencia en Internet, así que decidí crearlo yo mismo.

Creé una tabla muy simple con 500,000 filas:

CREATE TABLE test(
  ID INT(11) DEFAULT NULL,
  Description VARCHAR(20) DEFAULT NULL
)
ENGINE = INNODB
CHARACTER SET utf8
COLLATE utf8_general_ci;

Luego lo llené con datos aleatorios ejecutando este procedimiento almacenado:

CREATE PROCEDURE randomizer()
BEGIN
  DECLARE i INT DEFAULT 0;
  DECLARE random CHAR(20) ;
  theloop: loop
    SET random = CONV(FLOOR(RAND() * 99999999999999), 20, 36);
    INSERT INTO test VALUES (i+1, random);
    SET i=i+1;
    IF i = 500000 THEN
      LEAVE theloop;
    END IF;
  END LOOP theloop;
END

Luego creé los siguientes procedimientos almacenados para comparar simples SELECT, SELECT con LIKEy ordenando (SELECT con ORDER BY):

CREATE PROCEDURE benchmark_simple_select()
BEGIN
  DECLARE i INT DEFAULT 0;
  theloop: loop
    SELECT *
    FROM test
    WHERE Description = 'test' COLLATE utf8_general_ci;
    SET i = i + 1;
    IF i = 30 THEN
      LEAVE theloop;
    END IF;
  END LOOP theloop;
END;

CREATE PROCEDURE benchmark_select_like()
BEGIN
  DECLARE i INT DEFAULT 0;
  theloop: loop
    SELECT *
    FROM test
    WHERE Description LIKE '%test' COLLATE utf8_general_ci;
    SET i = i + 1;
    IF i = 30 THEN
      LEAVE theloop;
    END IF;
  END LOOP theloop;
END;

CREATE PROCEDURE benchmark_order_by()
BEGIN
  DECLARE i INT DEFAULT 0;
  theloop: loop
    SELECT *
    FROM test
    WHERE ID > FLOOR(1 + RAND() * (400000 - 1))
    ORDER BY Description COLLATE utf8_general_ci LIMIT 1000;
    SET i = i + 1;
    IF i = 10 THEN
      LEAVE theloop;
    END IF;
  END LOOP theloop;
END;

En los procedimientos almacenados anteriores utf8_general_ci se utiliza la intercalación, pero, por supuesto, durante las pruebas utilicé tanto utf8_general_ci y utf8_unicode_ci.

Llamé a cada procedimiento almacenado 5 veces para cada intercalación (5 veces para utf8_general_ci y 5 veces para utf8_unicode_ci) y luego calculó los valores promedio.

Mis resultados son:

benchmark_simple_select()

  • con utf8_general_ci: 9,957 ms
  • con utf8_unicode_ci: 10,271 ms

En este punto de referencia usando utf8_unicode_ci es más lento que utf8_general_ci en un 3,2%.

benchmark_select_like()

  • con utf8_general_ci: 11,441 ms
  • con utf8_unicode_ci: 12,811 ms

En este punto de referencia usando utf8_unicode_ci es más lento que utf8_general_ci en un 12%.

benchmark_order_by()

  • con utf8_general_ci: 11,944 ms
  • con utf8_unicode_ci: 12,887 ms

En este punto de referencia usando utf8_unicode_ci es más lento que utf8_general_ci en un 7,9%.

Esta publicación lo describe muy bien.

En breve: utf8_unicode_ci utiliza el algoritmo de clasificación Unicode como se define en los estándares Unicode, mientras que utf8_general_ci es un orden de clasificación más simple que da como resultado resultados de clasificación “menos precisos”.

Recuerda que puedes dar recomendación a este artículo si si solucionó tu problema.

¡Haz clic para puntuar esta entrada!
(Votos: 0 Promedio: 0)



Utiliza Nuestro Buscador

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *