Drie plekken waar MySQL een codering nodig heeft
- Kolom of tabel: de tekenset waarin de gegevens staan, zoals
utf8mb4oflatin1. - Verbinding: de tekenset waarin client en server met elkaar praten, in te stellen met
SET NAMES utf8mb4of in de verbindingsinstellingen. - Bestand: de codering waarmee een import wordt gelezen of een export wordt geschreven, in phpMyAdmin onder Tekenset van het bestand.
Als de drie niet overeenkomen, gaan tekens kapot. Het vaakst gebeurt dit zo: UTF-8-tekst is via een latin1-verbinding in een latin1-kolom geschreven. De applicatie ziet er goed uit, maar phpMyAdmin en de export tonen é.
Voor
"1","Zoë van der Heijden","Café-straat 12","Genève"
Na
"1","Zoë van der Heijden","Café-straat 12","Genève"
De tekensets controleren
SHOW VARIABLES LIKE 'character_set%';toont de instellingen van server en verbinding.SHOW CREATE TABLE klanten;toont de tekenset van de tabel en de kolommen.SELECT naam, HEX(naam) FROM klanten LIMIT 5;toont de echte bytes: in eenutf8mb4-kolom isC3A9eené, terwijlC383C2A9een al kapotteéis.
Een export of dump herstellen
- Exporteer de tabel in phpMyAdmin als SQL of CSV, of met
mysqldump --default-character-set=utf8mb4. - Sleep het bestand naar het vak hierboven. Mojibuster herstelt alleen de kapotte plekken; correcte tekens blijven ongemoeid.
- Controleer de herstelde plekken onder Wat is er veranderd? en download het bestand.
- Importeer het in een tabel met
utf8mb4en kies in het importvensterutf-8als tekenset. - Test eerst op een kopie voordat je de echte tabel vervangt.
De export verlaat je computer niet, wat belangrijk is bij klantgegevens. Staat er al dubbel gecodeerde tekst in? Lees dan à in plaats van accenten.
De oorzaak oplossen
- Maak nieuwe tabellen aan met
DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci. - Zet de verbinding van je applicatie op
utf8mb4, in PHP bijvoorbeeld metcharset=utf8mb4in de PDO-DSN. - Staan er UTF-8-bytes in een
latin1-kolom? Zet die dan niet direct om metCONVERT TO, want dan worden ze een tweede keer gecodeerd. De veilige weg loopt via een binair type: eerstMODIFY naam VARBINARY(255), danMODIFY naam VARCHAR(255) CHARACTER SET utf8mb4. - Vervangt MySQL tekens door
?, dan kan de kolom of verbinding ze niet weergeven. Wat al zo is opgeslagen, is verloren: meer over vraagtekens in plaats van letters.
Veelgestelde vragen
Waarom ziet alles er in mijn applicatie goed uit, maar niet in phpMyAdmin?
Omdat applicatie en database twee keer dezelfde fout maken: de applicatie schrijft UTF-8 over een latin1-verbinding en leest het op dezelfde manier terug. phpMyAdmin verbindt wel goed en toont dus wat er echt staat. Was de tekst al dubbel gecodeerd, lees dan over dubbele codering, en bij een WordPress-site over de WordPress-database.
Welke collation moet ik gebruiken?
utf8mb4_unicode_ci past bij de meeste applicaties; sinds MySQL 8 is utf8mb4_0900_ai_ci de standaard. De tekenset utf8mb4 is belangrijker, niet utf8, want die kan in MySQL geen emoji opslaan.
Werkt dit ook met MariaDB?
Ja. MariaDB gaat met tekensets om zoals MySQL en de commando’s zijn hetzelfde.
Hoe groot mag de dump zijn?
Tot 100 MB per bestand. Exporteer grotere databases tabel voor tabel.