Как обнаружить символы UTF-8 в столбце в кодировке Latin1 - MySQL - PullRequest
16 голосов
/ 16 февраля 2012

Я собираюсь выполнить утомительную и утомительную задачу преобразования базы данных из Latin1 в UTF-8.

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

В частности, я хочупроверьте, есть ли у меня символы UTF-8 в столбцах Latin1, что будет лучшим способом сделать это?Если затронуто только несколько строк, то я могу просто исправить это вручную.

Вариант 1. Выполнить дамп MySQL и использовать Perl для поиска символов UTF-8?

Вариант 2. ИспользоватьMySQL CHAR_LENGTH для поиска строк с многобайтовыми символами?например, SELECT name FROM clients WHERE LENGTH(name) != CHAR_LENGTH(name); Достаточно ли этого?

На данный момент я переключил кодировку Mysql-клиента на UTF-8.

Ответы [ 4 ]

47 голосов
/ 16 февраля 2012

Кодировка символов, как и часовые пояса, является постоянным источником проблем.

То, что вы можете сделать, - это искать любые символы "high-ASCII", поскольку это либо символы или символы с акцентом на LATIN1, либомногобайтового символа UTF-8.Указать разницу будет нелегко, если вы немного обманете.

Чтобы выяснить, какая кодировка верна, вы просто SELECT две разные версии и сравниваете визуально.Вот пример:

SELECT CONVERT(CONVERT(name USING BINARY) USING latin1) AS latin1, 
       CONVERT(CONVERT(name USING BINARY) USING utf8) AS utf8 
FROM users 
WHERE CONVERT(name USING BINARY) RLIKE CONCAT('[', UNHEX('80'), '-', UNHEX('FF'), ']')

Это сделано необычайно сложно, потому что движок MySQL regexp, похоже, игнорирует такие вещи, как \x80 и делает необходимым использование метода UNHEX().

Это приводит к следующим результатам:

latin1                utf8
----------------------------------------
Björn                Björn
9 голосов
/ 16 февраля 2012

Поскольку ваш вопрос не совсем понятен, давайте предположим несколько сценариев:

  1. До сих пор неправильное соединение: Вы неправильно подключались к своей базе данных, используя кодировку latin1, носохранили данные UTF-8 в базе данных (в этом случае кодировка столбца не имеет значения).Это тот случай, который я описал здесь .В этом случае это легко исправить: создайте дамп содержимого базы данных в файл через соединение latin1 .Это переведет неправильно сохраненные данные в неправильно правильно сохраненный UTF-8, способ, которым это работало до сих пор (см. Вышеупомянутую статью для подробных подробностей).Затем вы можете снова импортировать данные в базу данных через правильно установленное соединение utf8, и они будут сохранены в том виде, в каком должны быть.
  2. Некорректная кодировка столбца: Данные UTF-8 были вставлены встолбец latin1 через соединение utf8.В таком случае забудь, данные исчезли.Любой нелатинский символ 1 должен быть заменен на ?.
  3. До сих пор все хорошо, отныне добавлена ​​поддержка UTF-8: Вы имеете данные Latin-1, правильно хранящиеся в столбце latin1, вставленный через соединение latin1, но хочу расширить это, чтобы также разрешить данные UTF-8.В этом случае просто измените кодировку столбца на utf8.MySQL преобразует существующие данные для вас.Затем просто убедитесь, что для соединения с базой данных установлено utf8, когда вы вставляете данные UTF-8.
3 голосов
/ 28 января 2013
0 голосов
/ 16 февраля 2012

Я бы создал дамп базы данных и grep для всех допустимых последовательностей UTF8. Где взять его, зависит от того, что вы получите. На SO есть несколько вопросов об идентификации недействительного UTF8; Вы можете просто изменить логику.

Редактировать : Таким образом, любое поле, полностью состоящее из 7-битного ASCII, является безопасным, и любое поле, содержащее недопустимую последовательность UTF-8, можно считать Latin-1. Остальные данные должны быть проверены - если вам повезет, несколько очевидных замен зафиксируют абсолютное большинство (замените ¶ на Latin-1 и т. Д.).

...