Tři místa, kde MySQL potřebuje kódování
- Sloupec nebo tabulka: znaková sada, ve které jsou data uložená, například
utf8mb4,latin2nebocp1250. - Spojení: znaková sada, ve které spolu klient a server komunikují – nastavuje se příkazem
SET NAMES utf8mb4nebo v nastavení spojení. - Soubor: kódování, ve kterém se čte import nebo zapisuje export – v phpMyAdminu v poli Znaková sada souboru.
Pokud se tato tři nastavení neshodují, diakritika se rozbije. Nejčastější případ: text v UTF-8 se přes spojení latin1 zapsal do sloupce latin1. Aplikace vypadá v pořádku, ale phpMyAdmin a export ukazují Ä› a Ĺ™.
Před
"1","Jiřà Dvořák","PĹ™ĂÄŤná 12","TĹ™ebĂÄŤ"
Po
"1","Jiří Dvořák","Příčná 12","Třebíč"
Zkontrolujte znakové sady
SHOW VARIABLES LIKE 'character_set%';ukáže nastavení serveru a spojení.SHOW CREATE TABLE zakaznici;ukáže znakovou sadu tabulky a jejích sloupců.SELECT prijmeni, HEX(prijmeni) FROM zakaznici LIMIT 5;ukáže skutečné bajty: ve sloupciutf8mb4jeC3A9písmenoé, zatímcoC383C2A9je už rozbitéé.
Oprava exportu nebo dumpu
- Exportujte tabulku v phpMyAdminu jako SQL nebo CSV – nebo příkazem
mysqldump --default-character-set=utf8mb4. - Přetáhněte soubor do pole výše. Mojibuster opraví jen rozbitá místa, správné znaky zůstanou beze změny.
- Zkontrolujte opravená místa v části Co se změnilo? a stáhněte soubor.
- Naimportujte ho do tabulky s
utf8mb4a v dialogu importu zvolte znakovou saduutf-8. - Nejdřív to vyzkoušejte na kopii, než nahradíte skutečnou tabulku.
Export nikdy neopustí váš počítač – což u zákaznických dat záleží. Pokud jsou texty v databázi rozbité hned ve více vrstvách, přečtěte si stránku co je mojibake.
Odstraňte příčinu
- Nové tabulky vytvářejte s
DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci. Pro české řazení lze použít iutf8mb4_czech_ci. - Nastavte v aplikaci spojení
utf8mb4, v PHP například přescharset=utf8mb4v DSN pro PDO. - Pokud jsou bajty UTF-8 uložené ve sloupci
latin1, nepřevádějte ho přímo přesCONVERT TO– zakódovali byste je podruhé a vznikl by dvakrát zakódovaný text. Bezpečná cesta vede přes binární typ: nejdřívMODIFY prijmeni VARBINARY(255), potomMODIFY prijmeni VARCHAR(255) CHARACTER SET utf8mb4. - Pokud MySQL nahrazuje písmena znakem
?, sloupec nebo spojení je neumí uložit. Co je takto uloženo, je ztraceno – víc na stránce co je mojibake.
Časté otázky
Proč v aplikaci vše vypadá správně, ale v phpMyAdminu ne?
Protože aplikace a databáze dělají stejnou chybu dvakrát: aplikace zapisuje UTF-8 přes spojení latin1 a stejně to i čte. phpMyAdmin se připojuje správně, a proto ukazuje, co je skutečně uloženo.
Jakou collation zvolit?
utf8mb4_unicode_ci se hodí pro většinu aplikací, od MySQL 8 je výchozí utf8mb4_0900_ai_ci. Důležitější je znaková sada utf8mb4 – ne utf8, která v MySQL neuloží emoji.
Funguje to i s MariaDB?
Ano. MariaDB zachází se znakovými sadami stejně jako MySQL a příkazy jsou stejné.
Jak velký může být dump?
Až 100 MB na soubor. Větší databáze exportujte tabulku po tabulce.