A következő problémára akadtunk:
Adott egy adatbázis, aminek a táblái latin1/latin1_bin kódolásúak. Feladat: adatvesztés nélkül konvertáljuk át utf8/utf8_bin kódolásra az adatbázist. Két módját mutatjuk most be, egy egyszerűt, és nagyon bonyolultat. Természetesen mi a bonyolultat használtuk, mivel szeretjük a konzolt.
Első megoldásunk:
ALTER TABLE tablename CONVERT TO CHARACTER SET utf8 COLLATE utf8_bin
Ehhez igazán nincs hozzáfűzni valónk, annyiszor kell lefuttatni, ahány tábla van az adatbázisban. Többeket megkérdezve, senki sem merte 100%-ra állítani, hogy a konvertálás során egyetlen egy ékezet sem fog elbukni, és a már meglévő adataink valóban konvertálódnak-e.
A következő eljárás az, hogy kidumpoljuk az adatbázis tartalmát, majd latin1_bin/latin1 szavakat utf8_bin/utf8-ra cseréljük (ha adatbázisunkban szerepelhet ilyen szó, a regexpet kell tökéletesíteni a sed-nél), majd a dump-ból gyakorlatilag újra felépítjük az adatbázist. A szövegszerkesztős cserét elfelejthetjük, mivel a dumpunk mérete 1.1 GB, mondhatni böszme. Tehát szükségünk van egy linuxos konzolra, amiből elvégezzük a műveleteket, melyek sorban:
//kidumpoljuk a db-t
mysqldump –ppassword --add-drop-table --default-character-set=latin1 databasename > dbdump.sql
//cserélünk
find ./dbdump.sql -type f | xargs grep -l 'latin1_bin' | xargs sed -i -e 's/latin1_bin/utf8_bin/g'
find ./dbdump.sql -type f | xargs grep -l 'latin1' | xargs sed -i -e 's/latin1/utf8/g'
//latin kódolású fájlunkat utf8-ra tesszük. azért find, mert ha több file lenne, akkor find . -name "*.sql" .....
find . -name "dbdump.sql" -exec iconv -f ISO-8859-2 -t utf-8 {} -o {}.new ;
//a kész dumpot ezzel visszatolhatjuk
mysql -ppassword databasename < dbdump.sql.new
//kész
Természetesen a fenti scriptet mindenki a saját felelősségére használja.
A legtöbb dumpban a tábla karakterkódolása így szerepel:
CHARSET=latin1 vagy CHARSET=latin1_bin
Ezért a cserénél ha így adjuk meg 99%, hogy csak a táblák karakterkódolását fogja cserélni.
Ha a dumpban esetleg szóköz, tab vagy egyéb karakter is van az egyenlőség jel körül, akkor:
CHARSET[\ \t\r\n]*=[\ \t\r\n]*latin1
Figyeljünk arra is, hogy ilyenkor az új szöveghez is meg kell adnunk a CHARSET= -t is!
Ha az adatbázisunk valamelyik szöveg mezőjében vannak SQL tábla létrehozó scriptek (pl ha blogolunk az SQL-ről
) akkor kicsit macerásabb a helyzet. Erre az esetre egy ötlet:
Dumpoljuk az adatbázis tartalmát (tábla szerkezetet nem). Konvertáljuk utf8-ra.
Scriptben lekérjük az adatbázisban található táblák nevét. Ürítjük a táblákat majd mindegyiken lefuttatjuk az “első megoldás”-ban bemutatott scriptet. Majd a végén importáljuk a dumpot.
jah, itt a 3 megoldás is.
nagyon fasza
viszont az iconv -s sorban a ; előtt lemaradt egy \ , tehát helyesen:
find . -name “dbdump.sql” -exec iconv -f ISO-8859-2 -t utf-8 {} -o {}.new \;
legalábbis nálam csak így működik
nekem tán ment \ nélkül is. nem emlékszem.