MySQL od verze 4.1 podporuje nativně práci s různými znakovými sadami. Bohužel mnoho aplikací a dat v databázích vzniklo dříve a tuto podporu nevyužívají. Pak se uživatel může potýkat s mnoha problémy. Dnes se podíváme na to, jak ty nejčastější vyřešit.
Ve verzi 4.1 přibyla v MySQL podpora pro znakové sady a řazení. Ty se nastavují v několika úrovních – výchozí pro server, databázi a tabulku a nastavení pro jednotlivé sloupce. Pokud máme databáze ze starší verze MySQL, nemají přiřazen žádný způsob řazení a použije se výchozí pro server. Výchozí pro MySQL je latin1_swedish_ci, což je pro české podmínky poněkud nevhodné. Jméno řazení se skládá ze tří částí oddělených podtržítkem – první určuje znakovou sadu, druhá jazyk a třetí variantu porovnáván. Varianty porovnávání jsou tři:
Pro češtinu máme k dispozici tyto varianty: ucs2_czech_ci, utf8_czech_ci, cp1250_czech_cs, latin2_czech_cs.
Do phpMyAdmina přibyla podpora tyto vlastnosti MySQL ve verzi 2.6.3. Nastavit můžete výchozí porovnání pro databázi, tabulku a stejně tak i pro jednotlivé sloupce, které vidíme na přehledu tabulky.
Na úvodní stránce si také můžeme vybrat porovnávání použité pro zobrazování výsledů, ale použitá znaková sada bude vždy utf-8, protože stránky phpMyAdmina jsou v utf-8.
Pokud se nám některé znaky zobrazují v phpMyAdminovi špatně, je chybně nastavená jejich znaková sada. Znakovou sadu není možné měnit v přímo, protože MySQL server pak provede konverzi dat mezi těmito znakovými sadami a data budou nejspíš nenávratně poškozena! Pokud chceme jen změnit znakovou sadu sloupce, musíme ho nejprve převést na binární hodnotu (tedy na pole typu BINARY/VARBINARY/BLOB odpovídající CHAR/VARCHAR/TEXT) a pak zpět na původní typ jen s jinou znakovou sadou. Takto zůstanou data v nezměněné podobě a jen se změní znaková sada.
Po této změně je ale možné, že používané starší aplikace budou mít problém zobrazit správně data. Aplikace totiž bez explicitního určení znakové sady dostávají data ve výchozí znakové sadě serveru (což je latin1). Pokud k aplikaci máme zdrojové kódy, stačí hned za připojení k MySQL přidat SQL příkaz SET NAMES 'znaková sada'. Ten zajistí, že MySQL server bude posílat data ve znakové sadě, kterou aplikace používá. Pro češtinu máme opět čtyři možnosti: utf8, latin2, cp1250 a ucs2.
Komentáře
chyba v utf8_czech_ci
je nutné dodat, že ve verzi 4.1–5.0 (o ostatních nemám informace) je v porovnávání ‚uft8_czech_ci‘ chyba. znaky ‚č‘, ‚ř‘, ‚š‘ a ‚ž‘ jsou řazeny nesprávně a nejsou sprárovány s variantou bez háčku, takže např. výraz " ‚c‘ LIKE ‚č‘ " vrací false. to může být docela problém, pokud vyhledáváte v textu psaném ‚cestinou‘
lze to vyřešit jednoduše změnou na mezinárodní řazení ‚utf8_general_ci‘, které těmito neduny netrpí, ale ‚ch‘ bere jako dvě písmena a řadí jej jako ‚c‘ a ‚h‘
A proč tento problém
A proč tento problém nemůžu najít nikde v bug trackeru MySQL? Tak jsem to tam nahlásil – http://bugs.mysql.com/34371
ČSN 97 6030
popravdě, ani mě nenapadlo to zjišťovat.
docela mě to překvapilo a tak jsem si o tom zjistil trochu víc.
četl jsem zápornout (this is not a bug) odpověď MySQL AB a po pročtení ČSN 976030 (abecední řazení) s nimi bohužel musím souhlasit. samotná česká norma stanoví, že tato čtyři písmena (+ch) jsou považována za samostatné entity, zatímco ď, ť, ň jsou brána pouze jako varianta d, t, n (a samohlásky to samé). vychází to z logiky jazyka. zatímco d, t, n lze změkčit následujícím i nebo ě, tak u c, r, s, z nic takového možné není.
norma asi v tomhle ohledu (opět) zaspala dobu a je příliš přísná. nebere v potaz problémy skutečného jazyka, se kterými se musíme potýkat dnes a denně - tedy 'čeština' vs 'cestina'.
Unicode Consorcium (a tedy i MySQL AB) naši normu správně respektuje, takže řešení je v nedohlednu :( pořádek si musíme udělat nejdřív doma.
osobně zůstanu u řazení *_general_ci.