2010-11-01 60 views
16

Estoy tratando de convertir algunas tablas de mysql de latin1 a utf8. Estoy usando el siguiente comando, que parece funcionar en su mayoría.Convertir tablas de mysql de latin1 a utf8

ALTER TABLE tablename CONVERT TO CHARACTER SET utf8 COLLATE utf8_general_ci; 

Sin embargo, en una tabla me sale un error sobre una entrada de clave duplicada. Esto es causado por un índice único en un campo de "nombre". Parece que al convertir a utf8, cualquier carácter "especial" se indexa como su equivalente en inglés. Por ejemplo, ya hay un registro con un valor de campo de nombre de "Dru". Al convertir a utf8, un registro con "Drü" se considera duplicado. Lo mismo con "Patrick" y "Påtrìçk".

Aquí es cómo reproducir el problema:

CREATE TABLE `example` ( `name` char(20) CHARACTER SET latin1 NOT NULL, 
    PRIMARY KEY (`name`)) ENGINE=MyISAM DEFAULT CHARSET=latin1; 

INSERT INTO example (name) VALUES ('Drü'),('Dru'),('Patrick'),('Påtrìçk'); 

ALTER TABLE example convert to character set utf8 collate utf8_general_ci; 
ERROR 1062 (23000): Duplicate entry 'Dru' for key 1 

Respuesta

20

La razón por la cual las cadenas 'Drü' y 'Dru' evalúan como lo mismo es que en la colación utf8_general_ci, cuentan como "lo mismo". El propósito de una colación para un conjunto de caracteres es proporcionar un conjunto de reglas sobre cuándo las cadenas son iguales, cuándo una ordena antes que la otra, y así sucesivamente.

Si desea un conjunto diferente de reglas de comparación, debe elegir una intercalación diferente. Puede ver las intercalaciones disponibles para el juego de caracteres utf8 emitiendo SHOW COLLATION LIKE 'utf8%'. Hay un conjunto de intercalaciones destinadas a texto que se encuentra principalmente en un idioma específico; también está la intercalación utf8_bin que compara todas las cadenas como cadenas binarias (es decir, las compara como secuencias de 0 y 1).

3

UTF8_GENERAL_CI es el acento insensible.

Utilice UTF8_BIN o una intercalación específica de un idioma.