15
Jun/09
5

Comment convertir une DB de latin1 à UTF8

Un des défis d’être francophone consiste à bien gérer l’encoding. Je ne connais aucune personne n’ayant jamais eu de problème un jour où un autre. On m’a déjà approché pour trouver la manière la plus efficace de convertir une base de données de Latin1 à UTF8. Voici ce que j’ai trouvé. Ce n’est peut-être pas la manière la plus efficace, mais je n’ai pas eu problème après l’avoir testé. J’ai utilisé cette technique pour convertir une base de données de 115Go et tout c’est bien déroulé.

L’astuce consiste à transformer les chaines de caractères à un format binaire, pour ensuite les reconvertir en UTF8.

  1. ALTER DATABASE myDbNameDEFAULT CHARACTER SET utf8;
  2.  
  3. ALTER TABLE Groups DEFAULT CHARACTER SET utf8;
  4.  
  5. ALTER TABLE Groups MODIFY Domain VARBINARY(64) NULL DEFAULT NULL,
  6. MODIFY Type VARBINARY(64) NULL DEFAULT NULL,
  7. MODIFY Description VARBINARY(255) NULL DEFAULT NULL,
  8. MODIFY Name VARBINARY(200) NULL DEFAULT NULL;
  9.  
  10. ALTER TABLE Groups MODIFY Domain VARCHAR(64) CHARACTER SET utf8 NULL DEFAULT NULL,
  11. MODIFY Type VARCHAR(64) CHARACTER SET utf8 NULL DEFAULT NULL,
  12. MODIFY Description VARCHAR(255) CHARACTER SET utf8 NULL DEFAULT NULL,
  13. MODIFY Name VARCHAR(200) CHARACTER SET utf8 NULL DEFAULT NULL;

That’s it ! Super simple et efficace. Un coup qu’une string originalement Latin1 est convertie en format binaire, il n’y a plus de character set ni de collation qui tiennent. Elle devient un format binaire au même titre qu’une image JPG par exemple. Ensuite, on reprend ce format binaire et on réapplique un character set (et la collation par défaut dans mon exemple).

Il faut cependant ne pas négliger un aspect lors de cette conversion. Les caractères Latin1 utilise 1 byte par caractère alors qu’un caractère UTF8 utilisent 3 bytes par caractère. Si l’espace disque est une de vos contraintes, il ne faut pas prendre cette conversion à la légère!

Tagged as:
Comments (5) Trackbacks (0)
  1. starlett
    10:01 am on June 17th, 2009

    bonjour
    j’ai appliqué à la lettre les commandes pour effectuer une conversion latin1 vers utf8. Aucun problème pour la version binaire… par contre dès l’application du character set utf8 les données sont coupées dès qu’un accent est rencontré …

    exemple pour un titre : traitement complémentaire devient traitement compl

    quelque chose m’aurait échappé ?

    merci d’avance pour toute suggestion…

  2. PaT
    7:55 pm on June 18th, 2009

    C’est étrange… La longueur du champs est toujours la même ? Est-ce que la requête a produit une erreur ou un warning ? Ca a fait ca pour toutes les rows ou seulement un cas particulier ?

    Peut-être que cet enregistrement était corrompu d’une quelconque manière à l’avance ? C’était bien du Latin1 ?

    C’était un serveur qui roule sur une machine Windows ou Linux ?

  3. poof65
    5:03 am on June 25th, 2009

    Très intéressant ton blog, je travaille dans le milieu pro surtout avec mysql et tes posts m’aident vraiment à mieux comprendre l’outil que j’utilise.

  4. TheFly
    10:21 am on June 30th, 2009

    Avec égards, cette solution est peut-être attrayante pour les puristes mais difficilement applicable dans un cadre de production mutualisé où un administrateur système doit chaque jour convertir pour ses clients plusieurs bases de données de divers CMS qu’il ne connait pas intimement…

    Aussi, pour prendre MySQL par exemple (sous linux), comme mysqldump dump les caractères en utf-8 par défaut (depuis MySQL 5.x), il suffit de (1) dumper la base, (2) dropper toutes les tables & altérer la base en conséquence (première commande du post principal sans oublier le COLLATE), (3) modifier les CHARSET du dump file (sed ’s/CHARSET=latin1/CHARSET=utf8/’) et finalement (4) recharger le tout.

    Qu’en pensez-vous?

  5. PaT
    6:00 pm on June 30th, 2009

    @TheFly: C’est un autre manière oui. Assez efficace pour de petites bases de données.

    Parcontre, le procédé que j’ai expliqué peut aisément s’automatiser. Il suffit de créer un script qui va lire le schema de la base de données dans information_schema, et de créer dynamiquement les ALTER TABLE à rouler.

    Si vous devez régulièrement faire ce genre de manipulation, surtout dans le cadre d’un serveur mutualisé, je crois qu’il serait avantageux de faire un script pour le faire. Je vois bien un petit script bash ou php (ou autre): php convert.php –database databaseName –from latin1 –to utf8

Leave a comment

No trackbacks yet.