MySQL hat einen Zeichensatz namens utf8, der kein UTF-8 ist. Er speichert höchstens drei Bytes pro Zeichen, und jedes Emoji sowie einige seltenere Zeichen brauchen vier. Text, der eines enthält, wird entweder abgewiesen oder an dieser Stelle stillschweigend abgeschnitten — deshalb kann ein Kommentar ab einem Absatz einfach verschwinden.
Nehmen Sie utf8mb4 — überall
ALTER DATABASE shop CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
ALTER TABLE comments CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
Und in der Verbindung, das ist die vergessene Hälfte
// PDO
new PDO('mysql:host=localhost;dbname=shop;charset=utf8mb4', $u, $p);
; my.cnf
[mysqld]
character-set-server = utf8mb4
collation-server = utf8mb4_unicode_ci
Eine utf8mb4-Tabelle, über eine latin1-Verbindung gelesen, liefert entstellten Text und schreibt entstellten Text zurück. Die Tabelle stimmt, die Verbindung nicht, und die Daten verderben unterwegs. Setzen Sie beides.
Welche Sortierung
- utf8mb4_unicode_ci — sortiert und vergleicht sprachübergreifend nach Unicode-Regeln. Die sichere Voreinstellung.
- utf8mb4_0900_ai_ci — Voreinstellung von MySQL 8, neueres Unicode, etwas schneller.
- utf8mb4_bin — exakte Bytes. Für Token und Hashes, niemals für Namen.
Die Sortierung entscheidet über den Vergleich. Unter einer Sortierung ohne Groß-/Kleinschreibung trifft WHERE name = 'ali' auch auf Ali zu — bei einer Suche meist erwünscht, bei einem API-Schlüssel nicht.
Finden, was noch falsch ist
SELECT table_name, table_collation
FROM information_schema.tables
WHERE table_schema = 'shop' AND table_collation NOT LIKE 'utf8mb4%';
SELECT table_name, column_name, character_set_name
FROM information_schema.columns
WHERE table_schema = 'shop' AND character_set_name IS NOT NULL
AND character_set_name <> 'utf8mb4';
Spalten werden getrennt von Tabellen konvertiert. Eine als utf8mb4 deklarierte Tabelle kann noch latin1-Spalten aus alten Jahren enthalten — und genau die gehen kaputt.
Sichern Sie vor dem Umwandeln. Es schreibt jede Zeile neu, kann bei einer großen Tabelle dauern, und auf älteren Versionen beißen gelegentlich die Größenlimits der Indizes.
