MySQL Преобразование данных latin1 в UTF8

Я импортировал некоторые данные, используя LOAD DATA INFILE, в базу данных MySQL. Сама таблица и столбцы используют набор символов UTF8, но набор символов по умолчанию для базы данных — latin 1. Поскольку тип символов по умолчанию для базы данных — latin1, и я использовал LOAD DATA INFILE без указания набора символов, он интерпретировал файл как latin1, хотя данные в файле были в кодировке UTF8. Теперь у меня есть куча плохо закодированных данных в моем столбце UTF8. Я нашел эту статью, которая кажется для решения аналогичной проблемы, которая заключается в том, что «UTF8 вставлен в cp1251», но моя проблема заключается в том, что «Latin1 вставлен в UTF8». Я пытался редактировать запросы, чтобы преобразовать данные latin1 в UTF8, но не могу заставить его работать. Либо данные выходят такими же, либо еще более искаженными, чем раньше. Например, слово Квебек отображается как Квебек.

[ДОПОЛНИТЕЛЬНАЯ ИНФОРМАЦИЯ]

При выборе данных, заключенных в HEX(), Квебек имеет значение 5175C383C2A9626563.

Таблица создания (сокращенная) этой таблицы.

CREATE TABLE MyDBName.`MyTableName`
(
`ID` INT NOT NULL AUTO_INCREMENT, 
.......
`City` CHAR(32) NULL, 
.......
`)) ENGINE InnoDB CHARACTER SET utf8;

person Kibbee    schedule 17.09.2009    source источник
comment
опубликуйте оператор CREATE TABLE для рассматриваемой таблицы вместе с парой неработающих строк, но заверните неработающий столбец в hex(), например: SELECT HEX(name) FROM cities LIMIT 5. с этой информацией я могу помочь вам найти правильный способ исправить это в соответствии с этой статьей. (Кстати: мне нравится эта статья! Она несколько раз спасала мою задницу.)   -  person longneck    schedule 17.09.2009


Ответы (7)


У меня были подобные случаи в старых установках WordPress, проблема заключалась в том, что сами данные уже были в UTF-8 в базе данных Latin1 (из-за кодировки по умолчанию WP). Это означает, что не было реальной необходимости в преобразовании данных, кроме форматов ddbb и таблиц. По моему опыту, при выполнении дампа все запутывается, поскольку я понимаю, что MySQL будет использовать набор символов клиента по умолчанию, который во многих случаях теперь является UTF-8. Поэтому очень важно убедиться, что экспорт с тем же кодированием данных очень важен. В случае Latin1 DDBB с кодировкой UTF-8:

$ mysqldump –default-character-set=latin1 –databases wordpress > m.sql

Затем замените ссылки Latin1 в экспортированном дампе перед повторным импортом в новую базу данных в UTF-8. Вроде, как бы, что-то вроде:

$ replace "CHARSET=latin1" "CHARSET=utf8" \
    "SET NAMES latin1" "SET NAMES utf8" < m.sql > m2.sql

В моем случае эта ссылка очень помогла. Комментарий здесь на испанском языке.

person luison    schedule 21.12.2009
comment
Я видел дампы MySQL, где этой команды замены было недостаточно, потому что некоторые столбцы были явно установлены на latin1. Я сделал replace "latin1" "utf8mb4" <dump.latin1.sql >dump.utf8.sql, чтобы все в этой таблице использовало UTF-8. ЗАМЕТЬТЕ, однако, что latin1 больше нигде в дампе (содержимое поля) не встречается, и, просто чтобы убедиться, я проверил diff перед его импортом. - person basic6; 10.07.2014

Хотя это вряд ли еще актуально для ОП, я нашел решение в документации MySQL для ИЗМЕНИТЬ ТАБЛИЦУ. Я размещаю его здесь только для дальнейшего использования:

Предупреждение

Операция CONVERT TO преобразует значения столбцов между наборами символов. Это не то, что вам нужно, если у вас есть столбец с одним набором символов (например, latin1), но сохраненные значения фактически используют какой-то другой, несовместимый набор символов (например, utf8). В этом случае вы должны сделать следующее для каждого такого столбца:

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

Причина, по которой это работает, заключается в том, что при преобразовании в столбцы BLOB или из них не происходит преобразования.

person newtover    schedule 17.01.2012
comment
Со смешанным содержимым это не работает: Код: 1366 Состояние SQL: HY000 --- Неверное строковое значение: '\xE4chste...' для столбца 'kommentar' в строке 1 - person Wolfgang Fahl; 31.07.2014

LOAD DATA INFILE позволяет установить кодировку файла, которая должна находиться в:

http://dev.mysql.com/doc/refman/5.1/en/load-data.html

person Vladislav Rastrusny    schedule 17.09.2009
comment
Да, я хотел бы понять это раньше, но сейчас данные уже искажены. Я хотел знать, могу ли я исправить это без повторного импорта. - person Kibbee; 18.09.2009
comment
Да! Это вариант: [CHARACTER SET charset_name] - person Fernando Fabreti; 25.09.2012

Я написал, что http://code.google.com/p/mysqlutf8convertor/ для латиницы База данных в базу данных UTF-8. Все таблицы и поля изменить на UTF-8.

person saturngod    schedule 27.12.2009
comment
Возможно, вы захотите импортировать в github. Google Code теперь доступен только для чтения - person Otheus; 18.11.2016

Преобразование latin1 в UTF8 - это не то, что вы хотите сделать, вам нужно как бы обратное.

Если на самом деле произошло следующее:

  1. Строки UTF-8 интерпретировались как Latin-1 и транскодировались в UTF-8, искажая их.
  2. Теперь вы читаете или могли бы читать строки UTF-8 без дальнейшей интерпретации.

Что вы должны сделать сейчас:

  1. Прочитайте "UTF-8" без перекодирования.
  2. Преобразуйте его в латиницу-1. Теперь у вас должен быть оригинальный UTF-8.
  3. Теперь поместите его в столбец «UTF-8» без дальнейшего преобразования.
person DigitalRoss    schedule 17.09.2009

Недавно я завершил сценарий оболочки, который автоматизирует процесс преобразования. Также можно настроить создание пользовательских фильтров для любого текста, который вы хотите заменить или удалить. Например: удаление символов HTML и т. д. Также возможны белые и черные списки таблиц. Вы можете скачать его на сайте sourceforge: https://sourceforge.net/projects/mysqltr/

person user2192857    schedule 20.03.2013

Попробуй это:

1) Дамп вашей БД

mysqldump --default-character-set=latin1 -u username -p databasename < dump.sql

2) Откройте dump.sql в текстовом редакторе и замените все вхождения "SET NAMES latin1" на "SET NAMES utf8"

3) Создайте новую базу данных и восстановите файл дампа.

cat dump.sql | mysql -u root -p newdbname
person François    schedule 16.05.2012