2010-11-01 33 views
16

Je suis en train de convertir des tables mysql de latin1 en utf8. J'utilise la commande suivante, qui semble fonctionner principalement.Conversion de tables mysql de latin1 en utf8

ALTER TABLE tablename CONVERT TO CHARACTER SET utf8 COLLATE utf8_general_ci; 

Cependant, sur une table, j'obtiens une erreur sur une entrée de clé en double. Ceci est dû à un index unique sur un champ "nom". Il semble que lors de la conversion en utf8, tous les caractères "spéciaux" sont indexés comme leur équivalent anglais. Par exemple, il existe déjà un enregistrement avec une valeur de champ de nom "Dru". Lors de la conversion en utf8, un enregistrement avec "Drü" est considéré comme un doublon. La même chose avec "Patrick" et "Påtrìçk".

Voici comment reproduire le problème:

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 

Répondre

20

La raison pour laquelle les chaînes 'Drü' et 'Dru' évaluent comme étant le même est que dans le classement utf8_general_ci, ils comptent comme "le même". Le but d'un classement pour un jeu de caractères est de fournir un ensemble de règles pour savoir quand les chaînes sont identiques, quand l'une trie avant l'autre, et ainsi de suite.

Si vous voulez un ensemble différent de règles de comparaison, vous devez choisir un autre classement. Vous pouvez voir les classements disponibles pour le jeu de caractères utf8 en émettant SHOW COLLATION LIKE 'utf8%'. Il y a un tas de collations destinées au texte qui est principalement dans une langue spécifique; il existe également le classement utf8_bin qui compare toutes les chaînes en tant que chaînes binaires (c'est-à-dire les compare en tant que séquences de 0 et de 1).

3

UTF8_GENERAL_CI est insensible accent.

Utilisez UTF8_BIN ou un classement spécifique à une langue.