UTF-8 v MySQL

Databáza MySQL podporuje kódovú stránku UTF-8 od verzie 4.1. Ako default však MySQL používá kódovanie latin1 s triedením znakov (collation) latin1_swedish_ci, preto je potrebé zmeniť kódovanie na strane servera aj na strane klienta.

Na strane servera treba v konfiguračnom súbore my.cnf doplniť nasledujúce riadky do sekcie mysqld:
[mysqld]
character-set-server=utf8
collation-server=utf8_slovak_ci
Uvedená úprava spôsobí, že každá novovytvorená databáza bude implicitne používať kódovanie UTF-8 pre všetky objekty.

Pokiaľ databáza beží na serveri kde nie je možné zmeniť default na UTF-8, treba explicitne nastaviť kódovanie pri vytváraní každej databázy:

CREATE DATABASE db_name CHARACTER SET utf8 COLLATE utf8_slovak_ci;

Na strane klienta je potrebné pre každé spojenie určiť používané kódovanie príkazom:

SET CHARACTER SET utf8

 <?php
 php mysql_connect();
 mysql_select_db("db_name");
 mysql_query("SET CHARACTER SET utf8");
?>
Kódovanie na strane klienta nemusí byť totožné s kódovaním databázy, čo dáva aplikáciám značnú flexibilitu. Príkazom SET CHARACTER SET možno napr. dočasne zmeniť kódovanie spojenia na 'cp1250' a vložiť do databázy s kódovaním UTF-8 dáta vytvorené v OS Windows. MySQL zabezpečí konverziu do UTF-8 automaticky.

Upozornenie: MySQL používa kódovanie latin1 ako default aj na strane klienta. Ak by ste nepoužili príkaz SET CHARACTER SET utf8, databáza by sa snažila vkladané textové reťazce ešte raz konvertovať do UTF-8. Vzniklo by tzv. "dvojité" kódovanie - t.j. každý znak s diakritikou by zaberal namiesto dvoch až 4 bajty a nefungovali by konverzie kódovania ani triedenie podľa abecedy.

Od verzie MySQL 4.1.15 a 5.0.13 možno na strane servera zabezpečiť, aby sa na komunikáciu so všetkými klientmi používalo kódovanie UTF-8 - a to nasledujúcou úpravou súboru my.cnf:
[mysqld]
character-set-server=utf8
collation-server=utf8_slovak_ci
skip-character-set-client-handshake
Pri použití uvedeného nastavenia netreba na strane klienta používať príkaz SET CHARACTER SET utf8, takéto aplikácie však nemôžu byť prenesené na server s iným nastavením.



Konverzia existujúcej databázy

MySQL obsahuje od verzie 4.1 priamu podporu pre zmeny kódovania dát. Podmienkou jej úspešného použitia je však súlad deklarovaného kódovania v tabuľkách a stĺpcoch so skutočnosťou.

Pred konverziou databázy do UTF-8 je bezpodmienečne nutné odzálohovať dáta vytvorením exportu a presvedčiť sa, či sú deklarácie kódovania tabuliek správne. Ak boli slovenské dáta vkladané v kódovaní ISO-8859-2, mali by tabuľky obsahovať definíciu 'latin2', v prípade kódovania Windows-1250 definíciu 'cp1250'.

Ak sú definície kódovania správne, zmena kódovania databázy je jednoduchá:
  • ALTER DATABASE db_name CHARACTER SET utf8 COLLATE utf8_slovak_ci
    zmení default pre databázu na UTF-8

  • ALTER TABLE tbl_name CONVERT TO CHARACTER SET utf8 COLLATE utf8_slovak_ci
    skonvertujte celý obsah zadanej tabuľky do UTF-8.
Pri veľkom množstve tabuliek treba použiť php skript convert.txt, ktorý skonvertuje všetky tabuľky v databáze:
php convert.txt db_name utf8 utf8_slovak_ci



Oprava kódovania databázy

Ak tabuľky obsahujú nesprávnu definíciu kódovania (napr. 'latin1'), je pred samotnou konverziou do UTF-8 nevyhnutné zmeniť kódovanie tabuliek na reálne používané - inak by pri konverzii došlo k zámene znakov. Na to slúži php skript fixcharset.txt, ktorý opraví nesprávne definície kódovania v tabuľkách:
php fixcharset.txt db_name latin2_general_ci        alebo
php fixcharset.txt db_name cp1250_general_ci
Skript možno použiť iba v prípade, ak všetky tabuľky používajú rovnaké kódovanie. Po oprave kódovania treba skonvertovať dáta vyššieuvedeným postupom.

Ak databáza obsahuje "dvojité" kódovanie UTF-8 v dôsledku nesprávneho nastavenia klienta, je potrebné vyexportovať databázu v kódovaní latin1 - tým sa údaje stanú opäť platnými reťazcami v kódovaní UTF-8. V tomto prípade, ako aj pri iných neštandardných situáciách treba skontrolovať resp. upraviť definície kódovania v exporte textovým editorom, prípadne skonvertovať export príkazom iconv do UTF-8. Samotná konverzia dát sa uskutoční naimportovaním upraveného exportu do novej databázy s kódovaním UTF-8.