Это безопасный способ конвертировать таблицы MySQL из latin1 в utf-8?

Мне нужно изменить все таблицы в одной из моих баз данных с latin1 на utf-8 (с сопоставлением utf8_bin).

Я сбросил базу данных, создал из нее тестовую базу данных и выполнил следующее без каких-либо ошибок или предупреждений для каждой таблицы:

ALTER TABLE tablename CONVERT TO CHARSET utf8 COLLATION utf8_bin

Безопасно ли мне повторить это в реальной базе данных? Данные кажутся хорошими при проверке ...


person nfm    schedule 31.05.2011    source источник
comment
Почему-то я думаю, что преобразование — это нечто большее... в прошлом нам всегда приходилось сбрасывать и повторно создавать данные.   -  person tofutim    schedule 31.05.2011
comment
Да вот чего я боюсь! Я видел около 100 PHP-скриптов для дампа таблиц, регулярного выражения latin1, а затем повторной вставки. Я стремлюсь избежать этого, если это возможно, и я почти уверен, что все данные в настоящее время представляют собой нормальные символы (например, набор символов ASCII), но на самом деле не понимаю, как MySQL хранит и преобразует это.   -  person nfm    schedule 31.05.2011
comment
Почему бы вам не поместить несколько примеров крайних случаев в образец базы данных и не попробовать преобразовать...   -  person tofutim    schedule 31.05.2011
comment
Я думаю, вы можете сделать это на месте, если превратите все в блобы, выполните преобразование, а затем верните его обратно - см. dev.mysql.com/doc/refman/4.1/en/charset-conversion.html   -  person tofutim    schedule 31.05.2011


Ответы (3)


Следует рассмотреть 3 различных случая:

Значения действительно закодированы с использованием Latin1

Это согласованный случай: объявленная кодировка и кодировка содержимого совпадают. Это был единственный случай, о котором я рассказал в своем первоначальном ответе.

Используйте предложенную вами команду:

ALTER TABLE tablename CONVERT TO CHARSET utf8 COLLATE utf8_bin

Обратите внимание, что команда CONVERT TO CHARACTER SET появилась только в MySQL 4.1.2, поэтому любой, кто использует базу данных, установленную до 2005 года, должен был использовать трюк экспорта/импорта. Вот почему так много устаревших сценариев и документов в Интернете делают это по-старому.

Значения уже закодированы с использованием utf8

В этом случае вы не хотите, чтобы mysql преобразовывал какие-либо данные, вам нужно только изменить метаданные столбца.

Для этого вам нужно сначала изменить тип на BLOB, затем на TEXT utf8 для каждого столбца, чтобы не было преобразований значений:

ALTER TABLE t1 CHANGE c1 c1 BLOB;
ALTER TABLE t1 CHANGE c1 c1 TEXT CHARACTER SET utf8

Это рекомендуемый способ, и он явно задокументирован в Alter Table. Синтаксическая документация.

Значения используют в другой кодировке

В течение нескольких лет в некоторых дистрибутивах Linux кодировкой по умолчанию была Latin1. В этом случае вы должны использовать комбинацию двух методов:

  • Исправьте метаданные таблицы, используя трюк с типом BLOB.
  • Преобразуйте значения, используя CONVERT TO.
person Jerome    schedule 31.05.2011
comment
Зуд до -1. Простое преобразование сломает любые существующие акценты. - person Denis de Bernardy; 31.05.2011
comment
@Denis: Вы правы, я предположил, что содержимое таблицы было согласованным (например, кодировка Latin1 с содержимым latin1), хотя nfm не указал это. @nfm: какая кодировка эффективно используется контентом? - person Jerome; 01.06.2011
comment
Я запутался в этом, но пользовательские данные поступают с англоязычного веб-сайта с <meta charset="utf8">. Я почти уверен, что все данные в настоящее время используют английский алфавит и общие символы ASCII (@, $ и т. д.). Это отвечает на ваш вопрос? - person nfm; 01.06.2011
comment
Да, в этом случае вы не хотите, чтобы данные преобразовывались. Я обновил свой ответ соответственно. - person Jerome; 01.06.2011
comment
Спасибо за подробный ответ. Я считаю, что первый случай применим ко мне - глядя на настройки MySQL, клиент и сервер использовали latin1. В любом случае, я выполнил CONVERT TO CHARACTER SET для каждой таблицы без проблем, и все данные выглядят нормально. Спасибо! - person nfm; 01.06.2011
comment
COLLATION должен быть COLLATE (см. dev.mysql.com/doc/ refman/5.1/en/alter-table.html). - person Jakub Zalas; 01.11.2012

Прямое преобразование потенциально может сломать любые строки с символами, отличными от utf7.

Если у вас их нет (т. е. весь текст на английском), обычно все в порядке.

Однако, если у вас есть какие-либо из них, вам необходимо преобразовать все поля char/varchar/text в blob при первом запуске и преобразовать их в utf8 при последующем запуске.

Подробнее о процедурах см. в этой статье:

http://codex.wordpress.org/Converting_Database_Character_Sets

person Denis de Bernardy    schedule 31.05.2011
comment
Обратите внимание, что связанная статья немного устарела: в ней не используется ни один CONVERT TO, который существует уже 6 лет и значительно упрощает задачу. При этом это хороший справочник, и он работает как для старых, так и для новых баз данных. - person Jerome; 01.06.2011

Я делал это несколько раз в производственных базах данных в прошлом (преобразование из старой стандартной кодировки swedish в latin1), и когда MySQL встречает символ, который не может быть переведен в целевую кодировку, он прерывает преобразование и остается в неизменном виде. государство. Поэтому я считаю, что оператор ALTER TABLE работает.

person 0xCAFEBABE    schedule 31.05.2011