Ce problème touche les participants de ce site, et bien d'autres.
Vous avez énuméré les cinq principaux cas de CHARACTER SET
problèmes.
Meilleure pratique
A l'avenir, il est préférable d'utiliser CHARACTER SET utf8mb4
y COLLATION utf8mb4_unicode_520_ci
. (Une version plus récente de la collation Unicode est en préparation).
utf8mb4
est un sur-ensemble de utf8
en ce sens qu'il gère les codes utf8 à 4 octets, qui sont nécessaires pour les Emoji et une partie du chinois.
En dehors de MySQL, "UTF-8" fait référence à tous les codages de taille, et est donc effectivement le même que celui de MySQL. utf8mb4
pas utf8
.
J'essaierai d'utiliser ces orthographes et ces majuscules pour distinguer l'intérieur de MySQL de l'extérieur dans ce qui suit.
Aperçu de ce que vous devrait faire
- Réglez votre éditeur, etc., sur UTF-8.
- Les formulaires HTML devraient commencer comme suit
<form accept-charset="UTF-8">
.
- Faites en sorte que vos octets soient codés en UTF-8.
- Établir UTF-8 comme encodage utilisé dans le client.
- Avoir la colonne/table déclarée
CHARACTER SET utf8mb4
(Vérifiez auprès de SHOW CREATE TABLE
.)
-
<meta charset=UTF-8>
au début du HTML
- Les routines stockées acquièrent le jeu de caractères/collation actuel. Elles peuvent avoir besoin d'être reconstruites.
UTF-8 jusqu'au bout
Plus de détails pour les langages informatiques (et ses sections suivantes)
Testez les données
Visualisation des données avec un outil ou avec SELECT
ne sont pas dignes de confiance. Trop de clients de ce type, en particulier les navigateurs, essaient de compenser les encodages incorrects et vous montrent le texte correct même si la base de données est tronquée. Choisissez donc une table et une colonne dont le texte n'est pas en anglais et faites ce qui suit
SELECT col, HEX(col) FROM tbl WHERE ...
L'HEX pour un UTF-8 correctement stocké sera
- Pour un espace vide (dans n'importe quelle langue) :
20
- Pour l'anglais :
4x
, 5x
, 6x
ou 7x
- Pour la plupart de l'Europe occidentale, les lettres accentuées doivent être
Cxyy
- Cyrillique, hébreu et farsi/arabe :
Dxyy
- La plupart de l'Asie :
Exyyzz
- Emoji et un peu de chinois :
F0yyzzww
- Plus de détails
Causes et solutions spécifiques des problèmes constatés
Tronqué texte ( Se
para Señor
):
- Les octets à stocker ne sont pas codés en utf8mb4. Corrigez cela.
- Vérifiez également que la connexion pendant la lecture est UTF-8.
Diamants noirs avec des points d'interrogation ( Seor
para Señor
) ; l'un de ces cas existe :
Cas 1 (les octets originaux étaient no UTF-8) :
- Les octets à stocker ne sont pas encodés en utf8. Corrigez cela.
- La connexion (ou
SET NAMES
) pour le INSERT
et le site SELECT
n'était pas utf8/utf8mb4. Corrigez cela.
- Vérifiez également que la colonne dans la base de données est
CHARACTER SET utf8
(ou utf8mb4).
Cas 2 (octets originaux) étaient UTF-8) :
- La connexion (ou
SET NAMES
) pour le SELECT
n'était pas utf8/utf8mb4. Corrigez cela.
- Vérifiez également que la colonne dans la base de données est
CHARACTER SET utf8
(ou utf8mb4).
Les diamants noirs ne se produisent que lorsque le navigateur est configuré pour <meta charset=UTF-8>
.
Points d'interrogation (les normaux, pas les diamants noirs) ( Se?or
para Señor
):
- Les octets à stocker ne sont pas codés en utf8/utf8mb4. Corrigez cela.
- La colonne dans la base de données n'est pas
CHARACTER SET utf8
(ou utf8mb4). Corrigez cela. (Utiliser SHOW CREATE TABLE
.)
- Vérifiez également que la connexion pendant la lecture est UTF-8.
Mojibake ( Señor
para Señor
) : (Cette discussion s'applique également à Double encodage qui n'est pas nécessairement visible).
- Les octets à stocker doivent être encodés en UTF-8. Corrigez cela.
- La connexion lorsque
INSERTing
y SELECTing
Le texte doit spécifier utf8 ou utf8mb4. Corrigez cela.
- La colonne doit être déclarée
CHARACTER SET utf8
(ou utf8mb4). Corrigez cela.
- Le code HTML doit commencer par
<meta charset=UTF-8>
.
Si les données semblent correctes, mais ne sont pas triées correctement, alors soit vous avez choisi la mauvaise collation soit il n'existe pas de collation qui réponde à votre besoin, ou vous avez Double encodage .
Double encodage peut être confirmée en faisant le SELECT .. HEX ..
décrite ci-dessus.
é should come back C3A9, but instead shows C383C2A9
The Emoji should come back F09F91BD, but comes back C3B0C5B8E28098C2BD
C'est-à-dire que l'hexagone est environ deux fois plus long qu'il ne devrait l'être. Ceci est dû à la conversion de latin1 (ou autre) en utf8, puis au traitement de ces octets comme s'ils étaient en latin1. octets comme s'ils étaient en latin1 et en répétant la conversion. Le tri (et la comparaison) ne fonctionne pas correctement car il s'agit, par exemple, de trier comme si la chaîne était Señor
.
Corriger les données, si possible
Pour Troncature y Points d'interrogation les données sont perdues.
Pour Mojibake / Double encodage , ...
Pour Diamants noirs , ...
El Corrections sont énumérés ici. (5 solutions différentes pour 5 situations différentes ; choisissez avec soin) : http://mysql.rjweb.org/doc.php/charcoll#fixes_for_various_cases