В общем столкнулся давеча с такой ситуацией. Долго и нудно использовалось на работе приложение в котором составлялись заявки на аварии ну и сохранялись в базе MySQL.
Как-то не приходилось обращать внимания в какой кодировке, где, как и что хранится, а тут задумал переписать приложение, при этом захотелось задействовать ExtJS. Ну то, что этот фреймворк для отображения русского текста использует UTF8 нисколько не останавливало, в конце-концов в том-же PHP есть поддержка замечательного функционала iconv (не говоря уже о том, что iconv есть в Linux). И вот в этом месте поджидала необычная засада…
Таблица в базе была создана в кодировке Latin1, но данные в неё сохранялись из KOI8-U. Помимо всего прочего ситуация усугублялась тем, что системная локаль выставлена в UTF8. Простая смена через ALTER TABLE кодировки полей (или для всей таблицы) к успеху не приводила так как при этом выполнялось дополнительное преобразование кодировки, которое в общем-то делать было не к чему - данные и без того в KOI8.
Первое что пришло на ум это слить таблицу через mysqldump, затем конвертануть всё, что понадобится через iconv, через sed поменять описание для CHARSET и слить таблицу обратно. Но тут опять наметился геморой с двойной-тройной перекодировкой… короче чёрт ногу мог сломать быстрее нежели в этом всём разобраться. Данный путь был быстренько признан тупиковым.
Что же оставалось делать? На выручку пришло поле типа BLOB :)
Итак, пошагово. Заходим в mysql и делаем следующее:
Как-то не приходилось обращать внимания в какой кодировке, где, как и что хранится, а тут задумал переписать приложение, при этом захотелось задействовать ExtJS. Ну то, что этот фреймворк для отображения русского текста использует UTF8 нисколько не останавливало, в конце-концов в том-же PHP есть поддержка замечательного функционала iconv (не говоря уже о том, что iconv есть в Linux). И вот в этом месте поджидала необычная засада…
Таблица в базе была создана в кодировке Latin1, но данные в неё сохранялись из KOI8-U. Помимо всего прочего ситуация усугублялась тем, что системная локаль выставлена в UTF8. Простая смена через ALTER TABLE кодировки полей (или для всей таблицы) к успеху не приводила так как при этом выполнялось дополнительное преобразование кодировки, которое в общем-то делать было не к чему - данные и без того в KOI8.
Первое что пришло на ум это слить таблицу через mysqldump, затем конвертануть всё, что понадобится через iconv, через sed поменять описание для CHARSET и слить таблицу обратно. Но тут опять наметился геморой с двойной-тройной перекодировкой… короче чёрт ногу мог сломать быстрее нежели в этом всём разобраться. Данный путь был быстренько признан тупиковым.
Что же оставалось делать? На выручку пришло поле типа BLOB :)
Итак, пошагово. Заходим в mysql и делаем следующее:
- Устанавливаем текущую кодировку для таблицы:
SET NAMES LATIN1;
- Создаём новую таблицу с использованием структуры старой:
CREATE TABLE new LIKE old;
- Сохраняем все записи старой таблицы в новую:
INSERT INTO new SELECT * FROM old;
- Меняем кодировку на текущую системную:
SET NAMES UTF8;
- Затем для каждого текстового поля (char, varchar и т.п.) было проделано подобное преобразование:
ALTER TABLE new CHANGE field field BLOB; ALTER TABLE new CHANGE field field varchar(64) CHARACTER SET koi8u;
Безусловно, что цифровые, перечисляемые и другие типы полей подобной конвертации не подлежат.
Собственно после столь незначительных усилий таблица new стала содержать все данные из таблицы old только в правильной KOI8-U кодировке, вместо Latin1. Осталось подменить старую таблицу на новую:
RENAME TABLE old TO bak, new TO old;
В старые php-скрипты была добавлена инструкция mysql_query('SET NAMES KOI8U') и всё стало на свои места: пока ещё не написан полностью новый функционал - вполне корректно продолжили работать старые скрипты, а в новых, перед использованием json_encode текстовые поля из koi8-u приходится просто перекодировать в utf8 при помощи замечательной функции iconv ;)
Есть вероятность, что из BLOB можно было бы "вытащить" данные в UTF8, но пока мне это просто не нужно, так как старый функционал всё-таки заточен под KOI8-U.
Есть вероятность, что из BLOB можно было бы "вытащить" данные в UTF8, но пока мне это просто не нужно, так как старый функционал всё-таки заточен под KOI8-U.
Немає коментарів:
Дописати коментар