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

Поправяне на енкодинга на 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 ‘кодировка’.

Етикети: ,

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

  1. Петьо

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

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

  2. Гонзо

    Да, това бях забравил да опиша тука… За да не стане грешка може и нещо такова:

    sed -i ’s/CHARSET=latin1/CHARSET=utf8/g’ db.sql

  3. Ники

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

  4. Гонзо

    Да, верно, пълен съм с подобни грешки и все се чудя що нещо не работи… Сега го оправям!

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

Вашият имейл адрес няма да бъде публикуван. Задължителните полета са отбелязани с *