Блогът на Гонзо

Поправяне на енкодинга на MySQL база данни при ъпгрейд от 3.x/4.0 към 4.1/5

Пиша това, за да не се налага следващия път пак да откривам топлата вода, че пишман станах!

Сценария е следния – имаме MySQL база данни със кодиране на знаците в cp1251 и версия на сървъра по-малка от 4.1. Слагаме новата версия и на пръв поглед може и да си работят нещата, но търсенето не е както трябва, сортирането по varchar полета с кирилица не е правилно… Това е така, защото при ъпгрейта MySQL прекодира вътрешно знаците към UTF8, използвме подразбиращо се кодиране на връзката latin1 и получавме символи, което интерпретирани като cp1251 си се показват като кирилица. Обаче при търсене и сортиране нещата не работят както очакваме. Проблема се оправя така:

Първо дъмпиме базата данни:

shell> mysqldump -опции опции db > db.sql

След това използваме iconv за да направим файла cp1251:

shell> iconv -f utf8 -t latin1 db.sql >db_cp1251.sql

Ще кажете  „ама защо към latin1?“ Защото символите във базата данни са прекодирани от latin1 към UTF8.

После във файла променяме дефиницийте на таблиците да са с кодиране cp1251, като го отваряме в текстов редактор и заменяменавсякъде DEFAULT CHARSET latin1 със DEFAULT CHARSET cp1251. След това наливаме обратно дъмпа и готово:

shell> mysql -p db < db_cp1251.sql

UPDATE 3.02.2009: След проби и грешки с още няколко счупени бази и благодарение на коментарите по-долу, ето вкратце процедурата по прехвърляне на базата данни към правилно кодиране в cp1251:

shell> mysqldump -a -c -e --allow-keywords -q --default-character-set=latin1 -p базата > db.sql
shell> sed -i 's/latin1/cp1251/g' db.sql
shell> mysql -p базата < db.sql

От този момент нататък можете да извадите данните в какъвото кодиране имате нужда с помощта на SQL командата SET CHARACTER SET ‘кодировка’.

Етикети: ,

Comments (4)

Петьо профил

Сполай, това и други работи оправя, като например неправилно съхранена кирилица в latin1, която искаш да оправиш до utf8. След първата конверсия правиш още една, от cp1251 до utf-8.

sed -i ‘s/latin1/utf8/g’ db.sql пък заменя енкодинга на таблиците… разбира се, може да изгори ако го има в някой текст.

Ники профил

Благодаря за този постинг, много ми беше полезен. Само една поправка, командата не е ‘iconf’ а ‘iconv’, нали така?

Вашият коментар

XHTML: Allowed tags: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>