Mysql
 sql >> Base de données >  >> RDS >> Mysql

Comment éviter les caractères indésirables lors de la lecture de données dans plusieurs langues ?

Le Gujarati commence રેલવે , Corriger? Et le Malyalam commence നേപ , Corriger? Et l'anglais aurait dû inclure Bureau’s .

C'est le cas classique de

  • Les octets que vous avez dans le client sont correctement encodés en utf8. (Bureau est encodé dans le sous-ensemble Ascii/latin1 de utf8 ; mais n'est pas l'apostrophe ascii.)
  • Vous vous êtes connecté avec SET NAMES latin1 (ou set_charset('latin1') ou ...), probablement par défaut. (Cela aurait dû être utf8 .)
  • La colonne de la table a été déclarée CHARACTER SET latin1 . (Ou peut-être qu'il a été hérité de la table/base de données.) (Il aurait dû être utf8 .)

Le correctif pour les données est un "ALTER en 2 étapes".

ALTER TABLE Tbl MODIFY COLUMN col VARBINARY(...) ...;
ALTER TABLE Tbl MODIFY COLUMN col VARCHAR(...) ... CHARACTER SET utf8 ...;

où les longueurs sont assez grandes et les autres "..." ont n'importe quoi d'autre (NOT NULL , etc) était déjà sur la colonne.

Malheureusement, si vous avez beaucoup de colonnes avec lesquelles travailler, cela prendra beaucoup d'ALTER. Vous pouvez (devriez) MODIFY toutes les colonnes nécessaires à VARBINARY pour une seule table dans une paire de ALTERs .

Le correctif pour le code est d'établir utf8 comme connexion ; cela dépend de l'API utilisée en PHP. Les ALTERs modifiera la définition de la colonne.

Modifier

Vous avez VARCHAR avec le mauvais CHARACTER SET . Par conséquent, vous voyez Mojibake comme રેલ . La plupart des techniques de conversion tentent de préserver રેલ , mais ce n'est pas ce dont vous avez besoin. Au lieu de cela, faites un pas vers VARBINARY préserve les bits tout en ignorant l'ancienne définition des bits représentant les caractères encodés en latin1. La deuxième étape préserve à nouveau les bits, mais prétend maintenant qu'ils représentent des caractères utf8.