Быстрый способ преобразования charset базы данных MySQL

Недавно мне пришлось столкнуться с задачей перевода базы данных из одного charset в другой. Исходная база была в iso-8859-1, предстояло перевести её в utf-8. Задача усложнялась тем, что в исходной базе присутствовали символы из других языков (русский, испанский и, возможно, китайский).

Погуляв по Интернету и поискав в Google, я нашёл несколько решений.

  1. Способ, который мне очень понравился — TIP: Convert latin1 to UTF-8 in MySQL
    Вкратце (я немного изменил команды для повышения эффективности работы скрипта):
    [-]
    View Code Bash
    mysqldump -uuser -ppassword --default-character-set=latin1 -n -K --skip-set-charset --skip-create-options --skip-extended-insert --compatible=mysql40 --max_allowed_packet=64K dbname > latin_dump.sql
    iconv -f ISO-8859-1 -t UTF-8 latin_dump.sql > utf8_dump.sql
    mysql --max_allowed_packet=1M -uuser -ppassword --default-character-set=utf8 database_utf8 < utf8_dump.sql
    rm -f *.sql

    Идея состоит в том, что мы просто создаём дамп исходной базы, при этом указывая mysqldump, что никаких деклараций CHARSET и иже с ними указывать не надо, затем скармливаем полученный дамп iconv, который преобразует весь latin1 в utf8, а затем преобразованный файл отдаём mysql (при этом указываем, что charset по умолчанию у нас utf8).
    Из неприятного: не сработало :-) Как оказалось, из-за того, что cPanel создал базу (которая database_utf8) с DEFAULT CHARSET latin1. К счастью, лечится просто:

    [-]
    View Code MySQL
    ALTER DATABASE `database_utf8` CHARACTER SET 'utf8';
    ALTER DATABASE `database_utf8` COLLATE 'utf8_general_ci';
  2. Экзотика (ссылку, к сожалению, потерял): идея состоит в том, что каждый столбец (CHAR, VARCHAR, TEXT etc) преобразуется сначала в BLOB (при этом меняется только тип столбца и ничего более), а затем BLOB преобразуется в исходный тип, но уже с новым charset. Я как представлю себе, сколько там менять…
  3. Супер экзотика: Turning MySQL data in latin1 to utf8 utf-8. Без комментариев :-) Видимо, человеку очень надо было преобразовать базу :-)

И на закуску самый простой метод:

ALTER TABLE `table_name` CONVERT TO CHARACTER SET 'utf8';

Ибо как сказано в официальной документации:

If you want to change the table default character set and all character columns (CHAR, VARCHAR, TEXT) to a new character set, use a statement like this:
ALTER TABLE tbl_name CONVERT TO CHARACTER SET charset_name;

For a column that has a data type of VARCHAR or one of the TEXT types, CONVERT TO CHARACTER SET will change the data type as necessary to ensure that the new column is long enough to store as many characters as the original column. For example, a TEXT column has two length bytes, which store the byte-length of values in the column, up to a maximum of 65,535. For a latin1 TEXT column, each character requires a single byte, so the column can store up to 65,535 characters. If the column is converted to utf8, each character might require up to 3 bytes, for a maximum possible length of 3 × 65,535 = 196,605 bytes. That length will not fit in a TEXT column's length bytes, so MySQL will convert the data type to MEDIUMTEXT, which is the smallest string type for which the length bytes can record a value of 196,605. Similarly, a VARCHAR column might be converted to MEDIUMTEXT.

А мораль такова: если ничего не получается, прочтите, наконец, документацию! :-)

Добавить в закладки

Связанные записи

9
Март
2008

Комментарии к статье «Конвертирование базы данных MySQL из одного charset в другой» (4)  »

  1. bb says:

    В меморис!

    Вот спасибо тебе мил человек. Очень пригодилась твоя “заметка”.

    Пиши еще!

  2. Alex says:

    Метод из документации будет работать ТОЛЬКО есть данные в базе лежат в той же кодировке, которая объявлена для поля БД.
    Старые версии Вордпресса хранят данные в кодировке UTF8 в таблицах с кодировкой latin1 (при обновлении версии даже запрещается добавлять в старый конфиг константы CHARSET и COLLATION, как в новых версиях).
    Поэтому простой ALTER .. CONVERT не будет работать (он преобразует двухбайтовые символы в два разных символа). В этом случае сработает только конвертирование с использованием BLOB (2 пункт). При этом данные представляются просто как битовый поток, а потом к ним применяется перекодирование в UTF. А так как они до этого были записаны в UTF, то все закончится удачно. (К стати есть для этого скрипт, который находит текстовые поля и конвертирует их через BLOB в UTF, да и самому такой написать не большая проблема). Iconv по идее тоже не сработает (будет то же самое, как с CONVERT), но я не проверял…

    • Vladimir says:

      Alex, на самом деле вариантов здесь гораздо больше: всё зависит от charset’а базы, таблицы и соединения.

      Моя ошибка в том, что я описывал решение под свой конкретный случай, но не указал, какой из восьми возможных случаев был моим.

      Сейчас я пишу подробный обзор на эту тему.

  3. chaky says:

    первый способ прокатил, но без шага с iconv и без ALTER DATABASE `database_utf8` COLLATE ‘utf8_general_ci’

    в любом случае, спасибо за подсказку.

Подписаться на RSS-ленту комментариев к статье «Конвертирование базы данных MySQL из одного charset в другой» Trackback URL: http://blog.sjinks.org.ua/mysql/3-convert-mysql-database-from-one-charset-to-another/trackback/

Оставить комментарий к записи «Конвертирование базы данных MySQL из одного charset в другой»

Вы можете использовать данные тэги: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>

Оставляя комментарий, Вы выражаете своё согласие с Правилами комментирования.

Подписаться, не комментируя