|
|
|
|
|
|
|
|
|
|
Часто при переносе русскоязычных форумов на хостинг российского провайдеров (причем достаточно популярных среди пользователей форума) возникает проблема, что весь генерируемый форумом контент не читабелен – «крокозябры».
Здесь рассматривается проблема не соответствия кодировки старых данных в дампе и ожидаемой кодировки этих данных на сервере. Наиболее распространен случай, когда данные в БД в latin1 c coolation latin1_swedish, а для работы нужен cp1251.
Документация MySQL, http://dev.mysql.com/doc/refman/5.0/en/charset-conversion.html, говорит, что для конвертирования поля из одной кодировки в другую в начале необходимо текстовое поле со старой кодировкой привести к бинарному типу, тем самым убив все записи о старой кодировке текста, и выставить новую кодировку с новым collation (сравнением). И после этого, когда в таблице не останется ни одного поля со старой кодировкой, сделать смену кодировке и самой таблице.
При большом количестве таблиц в базе форума, эта задача ручным способом растягивается на часы. Однако умный человек дочитает документацию до конца, т.е. до комментариев и... И так же прочитает комментарии.
А там как раз панацея от нашей беды. MySQL Charset Converter - это уже немного измененная версия скипта автоматизации процесса, с более гибкой настройкой и возможностью использования результатов его работы через SSH (mysql dbname < instructions.sql)
Теперь все просто. Редактируем конфигурацию для скриптика.
$conn = mysql_connect("localhost", "login", "password"); </pcode> вместо localhost, login и password пишем свое <code php> $limitDB = false;
выставляем в true
$DBnames = array('test');
test меняем на имя своей БД.
Запускаем скрипт получаем кучу SQL инструкций вида
ALTER TABLE `ibf_cache_store` CHANGE `cs_key` `cs_key` varchar(255) CHARACTER SET BINARY NOT NULL; ALTER TABLE `ibf_cache_store` CHANGE `cs_key` `cs_key` varchar(255) CHARACTER SET cp1251 COLLATE cp1251_general_ci NOT NULL; ALTER TABLE `ibf_cache_store` CHANGE `cs_value` `cs_value` mediumtext CHARACTER SET BINARY NOT NULL; ALTER TABLE `ibf_cache_store` CHANGE `cs_value` `cs_value` mediumtext CHARACTER SET cp1251 COLLATE cp1251_general_ci NOT NULL; ALTER TABLE `ibf_cache_store` CHANGE `cs_extra` `cs_extra` varchar(255) CHARACTER SET BINARY NOT NULL; ALTER TABLE `ibf_cache_store` CHANGE `cs_extra` `cs_extra` varchar(255) CHARACTER SET cp1251 COLLATE cp1251_general_ci NOT NULL; ALTER TABLE `ibf_cache_store` DEFAULT CHARACTER SET cp1251 COLLATE cp1251_general_ci;
Все это дело замешиваем в файл latin12cp1251.sql.
ALTER TABLE ibf_topics DROP INDEX title; ALTER TABLE ibf_posts DROP INDEX post;
А в конце файла
ALTER TABLE ibf_topics ADD FULLTEXT (title); ALTER TABLE ibf_posts ADD FULLTEXT (post);
Закидываем это дело на сервер.
В шелле запускаем
mysql -uusername -ppassword dbname < /путь/до/latin12cp1251.sql
Ждем. И получаем новую кодировку в таблице.
UPD: Восстановление latin1 бэкапа на cp1251 клиентах MySQL - раскопал kript
Конвертация с использованием PHP решает большинство проблем, однако, как показывает практика, если конвертируемая таблица содержит большое количество данных, то использование выше описанного способа может потребовать от Вас достаточно большого запаса по времени (так таблица с 1 000 000+ сообщений у нас конвертировалась из koi8-r в cp1251 порядка 4 часов).
Именно такое решение было найдено с целью увеличить скорость процесса. Дамп базы MySQL - это набор SQL запросов. При этом все данные в дампе хранятся именно в той кодировке, что и в базе, с которой он был сделан. В UNIX системах существует достаточное количество прикладных програм, позволяющих осуществлять переконвертацию текстовых данных из одной кодировки в другую. Наиболее распространен iconv, именно его мы и будем использовать.
Для того что бы создать бэкап базы, с которым в последствии не будет проблем, необходимо определить кодировку таблиц в базе.
/home/dev/>mysql -h localhost -u dev -p database Enter password: Reading table information for completion of table and column names You can turn off this feature to get a quicker startup with -A Welcome to the MySQL monitor. Commands end with ; or \g. Your MySQL connection id is 556242 Server version: 5.0.45 FreeBSD port: mysql-server-5.0.45 Type 'help;' or '\h' for help. Type '\c' to clear the buffer. mysql>
Естественно что вместо dev необходимо писать имя пользователя базы данных, вместо database название базы данных Вашего форума.
В появившемся приглашении mysql пишем команду вывода полной структуры таблицы сообщений форума:
mysql> SHOW CREATE TABLE ibf_forums;
В итоге будет выведен похожий на ниже приведенный пример:
+------------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ | Table | Create Table | +------------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ | ibf_forums | CREATE TABLE `ibf_forums` ( `id` smallint(5) NOT NULL default '0', `topics` mediumint(6) default '0', `posts` mediumint(6) default '0', `last_post` int(10) default NULL, `last_poster_id` mediumint(8) NOT NULL default '0', `last_poster_name` varchar(255) default NULL, `name` varchar(128) NOT NULL default '', `description` text, `position` int(5) unsigned default '0', `use_ibc` tinyint(1) default NULL, `use_html` tinyint(1) default NULL, `status` varchar(10) default NULL, `password` varchar(32) default NULL, `password_override` varchar(255) default NULL, `last_title` varchar(250) default NULL, `last_id` int(10) NOT NULL default '0', `sort_key` varchar(32) default NULL, `sort_order` varchar(32) default NULL, `prune` tinyint(3) default NULL, `topicfilter` varchar(32) NOT NULL default 'all', `show_rules` tinyint(1) default NULL, `preview_posts` tinyint(1) default NULL, `allow_poll` tinyint(1) NOT NULL default '1', `allow_pollbump` tinyint(1) NOT NULL default '0', `inc_postcount` tinyint(1) NOT NULL default '1', `skin_id` int(10) default NULL, `parent_id` mediumint(5) default '-1', `sub_can_post` tinyint(1) default '1', `quick_reply` tinyint(1) default '0', `redirect_url` varchar(250) default '', `redirect_on` tinyint(1) NOT NULL default '0', `redirect_hits` int(10) NOT NULL default '0', `redirect_loc` varchar(250) default '', `rules_title` varchar(255) NOT NULL default '', `rules_text` text, `topic_mm_id` varchar(250) NOT NULL default '', `notify_modq_emails` text, `permission_custom_error` text, `permission_array` mediumtext, `permission_showtopic` tinyint(1) NOT NULL default '0', `queued_topics` mediumint(6) NOT NULL default '0', `queued_posts` mediumint(6) NOT NULL default '0', `forum_last_deletion` int(10) NOT NULL default '0', `forum_allow_rating` tinyint(1) NOT NULL default '0', `newest_title` varchar(250) default NULL, `newest_id` int(10) NOT NULL default '0', `meets` tinyint(1) NOT NULL, PRIMARY KEY (`id`), KEY `position` (`position`,`parent_id`) ) ENGINE=MyISAM DEFAULT CHARSET=koi8r | +------------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ 1 row in set (0.00 sec)
Кодировка написана в конструкции DEFAULT CHARSET=koi8r, а именно koi8r. Для latin1 будет DEFAULT CHARSET=latin1, для всего остального по аналогии.
Выходим из mysql
mysql> \q Bye /home/dev/>
После определения кодировки осталось выполнить команду создания дампа существующей базы. Делается это с помощью утилиты идущей в комлекте с mysql - mysqldump.
/home/dev/>mysqldump -h localhost -u dev -p --default-character-set=koi8r database > database.sql
Особое внимание к ключу –default-character-set=. После знака равно надо писать кодировку Вашей базы данных, которая была определена на первом шаге.
> database.sql означает, что мы перенаправляем результаты работы mysqldump в файл database.sql, т.е. дамп у нас будет именно там.
Остальные опции имеют такое же назначение как и в случае с mysql.
Теперь воспользовавшись утилитой iconv мы сможем сконвертировать дамп полученный на втором шаге в необходимую нам кодировку, делается это так:
/home/dev/>iconv -f koi8-r -t cp1251 database.sql > database.cp1251
Назначение ключей следующее:
-f koi8-r – конвертировать из кодировки koi8-r (у Вас может быть другая кодировка)
-t cp1251 – в кодировку cp1251
database.sql – файл который надо сконвертировать
> database.cp1251 – результаты конвертации запишутся сюда
Возможно появление проблем при конвертации, которые прервут процесс конвертирования. Это как правило происходит из-за невозможности найти соответствие символов одной кодировки в символы другой. В таких случаях стоит добавить еще один ключ (-c) в вызов iconv. Т.е. команда будет выглядеть уже так:
/home/dev/>iconv -c -f koi8-r -t cp1251 database.sql > database.cp1251
В этом случае при возникновении проблемы при конвертировании, символ будет пропущен, а конвертирование продолжится.
Все было бы замечательно и на четвертом шаге стоило бы уже делать восстановление базы из дампа на сервере, но есть одно «но». MySQL 4.1+ в дамп так же записываются директивы SET NAMES codepage; и DEFAULT CHARSET codepage; собственно эти директивы в нашем примере имеют следующий вид:
/home/dev/>cat database.cp1251 | grep 'SET NAMES' /*!40101 SET NAMES koi8r */; /home/dev/>cat database.cp1251 | grep 'DEFAULT CHARSET' ) ENGINE=MyISAM DEFAULT CHARSET=koi8r; ) ENGINE=MyISAM AUTO_INCREMENT=1532 DEFAULT CHARSET=koi8r; ) ENGINE=MyISAM DEFAULT CHARSET=koi8r;
Собственно так как дамп у нас должен быть в правильной cp1251 кодировке, то делаем замену в файле этих значений на новые:
/home/dev/> sed 's/SET NAMES koi8r/SET NAMES cp1251/g' < database.cp1251 > fixed.database.cp1251 /home/dev/> sed 's/DEFAULT CHARSET=koi8r/DEFAULT CHARSET=cp1251/g' < database.cp1251 > fixed.database.cp1251
Данную команду наглядно описать с русскими значениями:
sed 's/БЫЛО/СТАЛО/g' < ОТКУДА ЧИТАЕМ > КУДА ЗАПИСЫВАЕМ
Последний шаг восстановление базы.
Для начала удалим старую:
/home/dev/>mysql -u dev -p database -e 'DROP DATABASE database'
Enter password:
/home/dev/>
Создадим новую:
/home/dev/>mysql -u dev -p -e 'CREATE DATABASE database DEFAULT CHARSET cp1251'
Enter password:
/home/dev/>
Либо без удаления старой (если вдруг она нужна) просто создаем новую.
Все готово для того что бы начать разворачивание базы. Делается это так:
/home/dev/>mysql -u dev -p --default-character-set=cp1251 database < ./fixed.database.cp1251
Enter password:
/home/dev/>
Дамп развернут, кодировка базы cp1251, база готова для использования.
Работает на DokuWiki |