Valery's Mlog

Mindlog of a Freak
December 9th, 2005 by Valery Dachev

MySQL Upgrade

Как се минава от MySQL 4.0 към MySQL 4.1/5.x ? Еми трудно. Най-значимите промени са две:

  • съдържанието на TIMESTAMP полето вече не е “20051209215200”, ами нещо от типа на “2005-12-09 21:52:00”. Фокусите да се разчита на този формат вече не вършат работа и обработката трябва да се замени;
  • до преди да се появи 4.1 имахме един default charset, който не играеше особена роля. Сега вече си имаме символни множества (charsets) и правила за сравнения (collations) на ниво база, на ниво таблица и на ниво поле.

Доколкото вредните ефекти от първата промяна се оправят лесно, във втория случай това не е толкова тривиално. По подразбиране MySQL 4.0 ползва набор от символи latin1, но в общия случай това се регулира от default_charset опцията в my.cnf. Това няма абсолютно никакъв ефект върху съдържанието и работата на клиента. Може би само върху сравнението (тук може и да греша), респективно върху сортирането. Когато се мине към версия 4.1 този charset има особено значение при смяната на charset-а на колонката. Например, когато cp1251 информация е била съхранявана в latin1 поле. Ако се опитам да извикам заявката:

ALTER TABLE `table` CHANGE `field` `field` varchar(32) DEFAULT NULL CHARACTER SET cp1251;

, за да оправя charset-а на полето, съдържанието му ще бъде неправилно конвертирано, което в крайна сметка ще доведе до загуба на данни. Такова конвертиране се извършва винаги при преход от един character set към друг. Има един трик обаче, който може да се види на адрес http://dev.mysql.com/doc/refman/4.1/en/charset-conversion.html и той се състои в промяна на типа на колонката към binary и после обратно към изходния тип, но с желания character set. Така конвертиране не се извършва:
ALTER TABLE `table` CHANGE `field` `field` binary(32);<br />
ALTER TABLE `table` CHANGE `field` `field` varchar(32) DEFAULT NULL CHARACTER SET cp1251;

В дъното на същата страница има PHP скрипт написан от Shimon Doodkin, който обхожда всички бази, таблици и полета и прави въпросните промени. Той беше и базата, на която написах MySQL Charsets. Този инструмент върши същата работа, само че дава възможност работата да се ограничи до една база или до една таблица, визуално да се избира charset и/или collation, да генерира скрипта за конвертирането и разни други благинки. На мен свърши полезна работа и ще се радвам, ако и някой друг се възползва. :)

Comments

6 Responses to “MySQL Upgrade”
  1. Tova za converta ne e suvsem taka, neznam dali pri teb e srabotiulo, no az taka i ne uspqh da nakaram poleto da se convertne bez zaguba, za celta izpolzvah edin klas ot phpclasses, za convert ot edin charset kum drug, poopravih klasa – 15 puti podobrenie na skorostta i proasto convertnah dumpovete… razbira se tozi variant raboti i za postgre – a defakto az tam convertvah 1Gb baza :) ako ima nqkoioi zainteresovan da kaje :)

  2. При мен си работи – пушка. Няма проблем. Зависи как как конвертираш. Всъщност идеята е да не се прави конвертиране въобще, защото съдържанието си е това, което трябва да бъде, но описанието е различно. Не мисля, че какъвто и да е PHP скрипт ще се справи много по-бързо, от базата сама. Какво се получава при теб, ако опиташ с този скрипт ?

  3. ALTER TABLE `table_name` CONVERT TO CHARACTER SET utf8 COLLATE utf8_general_ci;

    Това ще ти свърши работа всъщност :) Аз го използвах с успех на много места. Единствено не конвертира BLOB-ове

  4. @wasp: Това върши работа, само ако конвертираш цялата таблица, а не отделни полета от нея и, като допълнение, наистина прави конвертиране на съдържанието. Проблемът с прехода към по-нова версия е, че таблиците например са в latin1, а съдържанието всъщност е в cp1251. Ако опиташ да направиш конвертиране, съдържанието ще бъде прецакано, особено ако го правиш към utf8. Същото е описано и в частта за “ALTER TABLE `table` CONVERT TO …” на http://dev.mysql.com/doc/refman/5.0/en/alter-table.html .

  5. @NikB: За радост на доста потребители, upgrade скриптовете поне в Debian вършат черната работа. :)

  6. Някои стари клиенти изискват промяна на интерпретирането на паролите от 4.1.
    Та sled snqmata na 4.0 s 4.1 се препоръчва изпълняването на следния SQL:
    SET PASSWORD FOR
    ‘user’@’host’ = OLD_PASSWORD(‘password’);

Leave a Reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.

%d bloggers like this: