Пиша това, за да не се налага следващия път пак да откривам топлата вода, че пишман станах!
Сценария е следния – имаме 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 ‘кодировка’.
Сполай, това и други работи оправя, като например неправилно съхранена кирилица в latin1, която искаш да оправиш до utf8. След първата конверсия правиш още една, от cp1251 до utf-8.
sed -i ‘s/latin1/utf8/g’ db.sql пък заменя енкодинга на таблиците… разбира се, може да изгори ако го има в някой текст.
Да, това бях забравил да опиша тука… За да не стане грешка може и нещо такова:
sed -i ’s/CHARSET=latin1/CHARSET=utf8/g’ db.sql
Благодаря за този постинг, много ми беше полезен. Само една поправка, командата не е ‘iconf’ а ‘iconv’, нали така?
Да, верно, пълен съм с подобни грешки и все се чудя що нещо не работи… Сега го оправям!