?

Log in

Перенос базы из mysql ранних версий в mysql-4.1 без проблем с кодировкой - Tutorial.Ru

> Свежие записи
> Архив
> Друзья
> Личная информация
> Tutorial.Ru

Апрель 19, 2006


Previous Entry Поделиться
nmind
05:17 pm - Перенос базы из mysql ранних версий в mysql-4.1 без проблем с кодировкой
Туториал: Перенос базы из mysql ранних версий в mysql-4.1 без проблем с кодировкой

Автор: nmind . konstantin kalachev / http://tutorial.ru

Дата последней модификации: 2006.04.19

Полезные ресурсы:
- http://dev.mysql.com/doc/refman/4.1/en/charset-connection.html

Устанавливалось на:
MySQL 4.1.15-max

- Пример переноса mysql-дампа из базы mysql-4.0.15a в базу mysql-4.1.15-max

При обновлении базы mysql с ранних версии до версии 4.1 многие сталкиваются с проблемой битой кодировки. Происходит это потому,что в 4.1 используется только utf-8 и все символы из дампов конвертируются в него. То есть, если у вас был дамп в кодировке win1251 , то при импортировании его в базу mysql-4.1 он переведется в utf-8 и восстановить текст уже не будет представляться возможным.

Решение - говорить mysql о том в какой кодировке ему будет импортироваться текст. Для того, чтобы лучше понять как это делается приведу пример для базы, к которой у вас нет другого доступа, кроме как mysql интерфейс. Например, это может быть зарубежный хостинг.

Предположим, что у нас есть sql-дамп таблицы my_win1251_table . Его кодировка win1251. Добавляем в начало файла строки, которые будут менять значение переменных для mysql-сессии. Получается:


SET collation_connection = cp1251_general_ci; SET collation_database = cp1251_general_ci; SET collation_server = cp1251_general_ci; SET character_set_client = cp1251; SET character_set_connection = cp1251; SET character_set_database = cp1251; SET character_set_results = cp1251; SET character_set_server = cp1251; DROP TABLE IF EXISTS `my_win1251_table`; CREATE TABLE `my_win1251_table` ( `content` varchar(100) NOT NULL default '' ) TYPE=MyISAM; INSERT INTO `my_win1251_table` VALUES ('Текст на русском из базы mysql-4.0.15a');


Теперь заливаем дамп в базу mysql-4.1


mysql -usomeuser -psomepasswd somedb < dump.sql


Если теперь посмотреть на дамп из базы mysql-4.1 то он будет выглядеть вот так


DROP TABLE IF EXISTS `my_win1251_table`; CREATE TABLE `my_win1251_table` ( `content` varchar(100) NOT NULL default '' ) ENGINE=MyISAM DEFAULT CHARSET=cp1251; LOCK TABLES `my_win1251_table` WRITE; INSERT INTO `my_win1251_table` VALUES ('РўРчРєС?С' Р?Р° С?С?С?С?РєР?Р? РёР· Р+азС< mysql-4.0.15a'); UNLOCK TABLES;


Обратите внимание, что в insert-е текст поля теперь в формате utf-8. И он длиннее чем оригинал, потому что utf-8 тратит два байта на один символ. Именно поэтому при выводе этого текста на html-страницу будут появляться знаки вопроса.

Так же стоит обратить внимание на текст нового дампа "CREATE TABLE ... DEFAULT CHARSET=cp1251;" В mysql-4.1 появился параметр charset, который присваивается как базе, так и каждой таблице в отдельности.

Для того, чтобы добиться не только правильного ввода данных, но и вывода нужно сказать mysql базе о том, что мы хотим получить от нее данные в кодировке win1251, в чем нам поможет команда "SET NAMES cp1251;".


mysql -usomeuser -psomepasswd somedb mysql> SET NAMES cp1251; mysql> SELECT * FROM my_win1251_table; +----------------------------------------+ | content | +----------------------------------------+ | Текст на русском из базы mysql-4.0.15a | +----------------------------------------+ 1 row in set (0.00 sec)


- Глобальные способы решения проблемы

Пример, приведеный выше доступен всем, у кого есть доступ к mysql инерфейсу. Но если у вас есть права root на сервере, то можно постараться заранее предугадать проблему с кодировками.

Для этого в файле /etc/my.cnf можно прописать следующее


[client] default-character-set = cp1251 [mysqld] default-character-set = cp1251 init-connect = 'SET NAMES cp1251'


Причем, у меня все заработало правильно и без указания "init-connect" , но многим помогает именно эта строчка.

Так же можно скомпилировать mysql с указанием параметров configure "--with-charset=cp1251 --with-collaption=cp1251_general_ci"

- Переменные mysql-4.1 и странное поведение команды "SET NAMES cp1251;" и "SET CHARACTER SET cp1251;"

Если у вас все получилось и больше ничего не нужно от базы эту часть читать не обязательно.

В интернете громадное количество информации по этой проблеме, но почти каждый ответ заключается в совете задавать команды "SET NAMES cp1251;" и "SET CHARACTER SET cp1251;" после соединения. Вот пример mysql-сесси, по которой явно видно, что mysql-4.1 меняет только часть переменных при выполнении этих команд.


mysql> SET NAMES cp1251; Query OK, 0 rows affected (0.00 sec) mysql> SET CHARACTER SET cp1251; Query OK, 0 rows affected (0.00 sec) mysql> SHOW VARIABLES LIKE 'character_set%'; +--------------------------+----------------------------------------+ | Variable_name | Value | +--------------------------+----------------------------------------+ | character_set_client | cp1251 | | character_set_connection | latin1 | | character_set_database | latin1 | | character_set_results | cp1251 | | character_set_server | latin1 | | character_set_system | utf8 | | character_sets_dir | /usr/local/mysql/share/mysql/charsets/ | +--------------------------+----------------------------------------+ 7 rows in set (0.00 sec) mysql> SHOW VARIABLES LIKE 'collation%'; +----------------------+-------------------+ | Variable_name | Value | +----------------------+-------------------+ | collation_connection | latin1_swedish_ci | | collation_database | latin1_swedish_ci | | collation_server | latin1_swedish_ci | +----------------------+-------------------+ 3 rows in set (0.01 sec)


В документации написано, что "SET NAMES" меняет переменные "character_set_client" , "character_set_results" , "character_set_connection" , но на деле переменная "character_set_connection" остается прежней. Так же там написано, что "SET CHARACTER SET" меняет переменные "character_set_client" , "character_set_results" , "collation_connection" , но на самом деле "collation_connection" остается прежней.

А вот пример ручной замены всех возможных переменных


mysql> SHOW VARIABLES LIKE 'character_set%'; +--------------------------+----------------------------------------+ | Variable_name | Value | +--------------------------+----------------------------------------+ | character_set_client | latin1 | | character_set_connection | latin1 | | character_set_database | latin1 | | character_set_results | latin1 | | character_set_server | latin1 | | character_set_system | utf8 | | character_sets_dir | /usr/local/mysql/share/mysql/charsets/ | +--------------------------+----------------------------------------+ 7 rows in set (0.00 sec) mysql> SHOW VARIABLES LIKE 'collation%'; +----------------------+-------------------+ | Variable_name | Value | +----------------------+-------------------+ | collation_connection | latin1_swedish_ci | | collation_database | latin1_swedish_ci | | collation_server | latin1_swedish_ci | +----------------------+-------------------+ 3 rows in set (0.00 sec) mysql> SET collation_connection = cp1251_general_ci; Query OK, 0 rows affected (0.00 sec) mysql> SET collation_database = cp1251_general_ci; Query OK, 0 rows affected (0.00 sec) mysql> SET collation_server = cp1251_general_ci; Query OK, 0 rows affected (0.00 sec) mysql> SET character_set_client = cp1251; Query OK, 0 rows affected (0.00 sec) mysql> SET character_set_connection = cp1251; Query OK, 0 rows affected (0.00 sec) mysql> SET character_set_database = cp1251; Query OK, 0 rows affected (0.00 sec) mysql> SET character_set_results = cp1251; Query OK, 0 rows affected (0.00 sec) mysql> SET character_set_server = cp1251; Query OK, 0 rows affected (0.00 sec) mysql> SHOW VARIABLES LIKE 'character_set%'; +--------------------------+----------------------------------------+ | Variable_name | Value | +--------------------------+----------------------------------------+ | character_set_client | cp1251 | | character_set_connection | cp1251 | | character_set_database | cp1251 | | character_set_results | cp1251 | | character_set_server | cp1251 | | character_set_system | utf8 | | character_sets_dir | /usr/local/mysql/share/mysql/charsets/ | +--------------------------+----------------------------------------+ 7 rows in set (0.00 sec) mysql> SHOW VARIABLES LIKE 'collation%'; +----------------------+-------------------+ | Variable_name | Value | +----------------------+-------------------+ | collation_connection | cp1251_general_ci | | collation_database | cp1251_general_ci | | collation_server | cp1251_general_ci | +----------------------+-------------------+ 3 rows in set (0.00 sec)


Как видите, теперь все нормально. Не стоит заменять переменную "character_set_system" , она отвечает за внутренюю кодировку базы и всегда будет utf-подобной.

- Ключевые слова

вопросы дамп mysql база знаки вопроса кои кои-8 koi koi-8 битая кодировка set names cp1251 set character set 1251 dump дамп

(4 комментария | Оставить комментарий)

Comments:


[User Picture]
From:nmind
Date:Апрель 19, 2006 03:18 pm
(Link)
А для тех случаев, когда информация видна из базы 4.1 через веб, но при создании дампа или указании кодировок все тут же ломается можно использывать phpmyadmin 2.5.4 , например. Он еще не знает что такое utf-8 и сделает нормальный дамп, который потом можно будет перезалить в уже настроеную базу, изменив в нем CHARSET для каждой таблицы руками.
[User Picture]
From:nmind
Date:Сентябрь 13, 2006 01:57 pm
(Link)
Выяснил, что можно обойтись изменением всего трех переменных.

Пример для php:
mysql_query ("set character_set_client='cp1251'");
mysql_query ("set character_set_results='cp1251'");
mysql_query ("set collation_connection='cp1251_general_ci'");
From:kinah_ebarts
Date:Июль 13, 2010 03:58 pm
(Link)
добавь в друзья - nmind
From:(Anonymous)
Date:Октябрь 18, 2010 12:15 pm

Монсреский гайд по импорту mysql

(Link)
Мучаюсь целы день, вот сегодня попробую использовать эти команды

> Go to Top
LiveJournal.com