MySQL kann UTF-8… falsch. Besser gesagt: Ungenau. MySQL kann UTF-8, aber das heißt da anders:
Ein Zeichen in UTF-8 ist (bis zu) vier Bytes lang, “UTF-8” in MySQL kann aber nur bis zu drei. Deswegen fällt der Unterschied oft gar nicht auf, oder erst beim ersten Zeichen, das vier Bytes braucht. Will man echtes UTF-8, muss man einiges umkonfigurieren; in Kurzform:
- SQL muss in der Version 5.3.3+ vorhanden sein, siehe Link oben
- Jede Datenbank, jede Tabelle (ggf. jede Spalte) müssen auf “
CHARSET=utf8mb4 COLLATE utf8mb4_unicode_ci
” umgestellt werden- Dabei zu beachten: InnoDB kann wohl nur 767 Bytes pro Index Schlüssel. Wenn man vier (statt drei) Bytes pro Zeichen rechnet, sind das bsplw. nur 191 (statt 255) Zeichen!
- Das gilt auch für Typen wie
TINYTEXT
, die wohl nur 255 Bytes = 63 Zeichen bei 4 Byte/Zeichen speichern können. Ggf. ist hier ein anderer Typ zu wählen
- ggf. Server, Client, etc. umstellen (dabei hilft “
SHOW VARIABLES WHERE Variable_name LIKE 'character\_set\_%' OR Variable_name LIKE 'collation%';
“) - ggf. Datenbank reparieren und optimieren (war bei mir nicht nötig, ich habe alle Tabellen neu angelegt):
1 2 3 |
# For each table REPAIR TABLE table_name; OPTIMIZE TABLE table_name; |
bzw.
1 |
mysqlcheck -u root -p --auto-repair --optimize --all-databases |
Insbesondere bei Punkt 3 hängt es bei CodeIgniter, btw. Wenn man in der Datenbank-Config
1 2 |
$db['default']['char_set'] = 'utf8'; $db['default']['dbcollat'] = 'utf8_unicode_ci'; |
stehen hat, dann ist das ebenfalls nicht das echte UTF-8. Stattdessen korrekt ist:
1 2 |
$db['default']['char_set'] = 'utf8mb4'; $db['default']['dbcollat'] = 'utf8mb4_unicode_ci'; |
Update
Das Problem betrifft auch mysqldump: Will man die eine utf8mb4-Datenbank dumpen, muss man das explizit sagen, denn mysqldump nutzt per Default nur utf8 (Quelle):
1 |
mysqldump --default-character-set=utf8mb4 -u [uname] -p"[pass]" db_name > db_backup.sql |
Das ist so tief verankert, dass auch Dumps über Tools wie Sequel Pro nur utf8 nutzen m(
Uh… wieder danke. O.o Wir nutzen auch utf8_general_ci durchgehend… und wegen Internationalisierung in den kommenden Monaten bei uns könnte das wichtig werden. Weiß ich Bescheid…