Проблема с кодировкой UTF-8 при импорте файла sql

У меня есть сервер, на котором размещена MySQL, сообщает PHPMyAdmin:

Server version: 5.1.56-community
MySQL charset: UTF-8 Unicode (utf8)

Я экспортирую sql, используя либо mysqldump -uroot -p database > file.dump, либо mysqldump -uroot -p database -r file.dump (в любом случае оба сгенерированных файла идентичны).

Локально я установил MySQL 5.5 и HeidiSQL 9.5.

Поскольку файл SQL сервера my.ini имеет:

default-character-set=utf8

Я изменил локальный файл my.ini, чтобы

default-character-set=utf8

Но также:

character-set-server=utf8

Они оба были установлены на latin1. Не знаю, почему у меня здесь установлено character-set-server, а на сервере нет. Так или иначе.

Теперь я запускаю HeidiSQL, он показывает utf8mb4 ссылок вместо utf8 для параметров сеанса. Я не знаю почему:

введите здесь описание изображения

Теперь я импортирую свой файл дампа и вижу, что даже если все явно настроено в utf8, похоже, у меня есть некоторые проблемы с кодировкой.

На сервере вижу: введите здесь описание изображения

Локально в HeidiSQL я вижу: введите здесь описание изображения

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

Я делаю что-то неправильно?

Обратите внимание, что если я устанавливаю HeidiSQL на сервер, на вкладке переменных отображаются те же значения для параметров Session и Global, а à отображается правильно.

Так что это может быть основной причиной проблемы, но я не знаю, как это исправить. Если я изменю значения Session перед импортом файла sql, это не решит проблему, а также значения вернутся к utf8mb4, когда я снова запущу HeidiSQL.


person jpo38    schedule 21.09.2018    source источник
comment
Почему вы используете 7-летнюю версию mysql?   -  person Evert    schedule 21.09.2018
comment
@Evert: Потому что он не обновлялся последние 7 лет ;-) Вот почему я работаю над этим сегодня, пытаясь перенести это на новую систему.   -  person jpo38    schedule 21.09.2018
comment
Дамп в кодировке UTF-8? Когда вы открываете его в текстовом редакторе явно как UTF-8, символы выглядят нормально…?   -  person deceze♦    schedule 21.09.2018
comment
@deceze: я открыл файл с помощью Notepad ++, что позволило мне выбрать кодировку. Символ à выглядит правильно при выборе UTF-8 (по умолчанию). Похоже, что файл закодирован в UTF-8.   -  person jpo38    schedule 21.09.2018


Ответы (3)


Благодаря комментарию deceze я смог решить проблему.

В HeidiSQL, когда я выбираю файл sql для выполнения, на самом деле есть опция «ncoding», которую я изначально не заметил ;-)

Если я сохраняю «автоматическое определение», импорт генерирует плохой контент (с символами моджибаке)

Если я форсирую "UTF-8", импорт будет идеальным

Не знаю, почему HeidiSQL не может автоматически определить кодировку...

person jpo38    schedule 21.09.2018

Несколько мыслей:

Похоже, вы правильно установили набор символов. Тот факт, что HeidiSQL отображает другой набор символов, вероятно, связан с тем, что клиенты сами устанавливают набор символов.

Например, ваш сервер mysql может использовать «Набор символов A» по умолчанию. Если клиент подключается и говорит, что ему нужен «Набор символов B», сервер преобразует его на лету.

utf8mb4 является надмножеством (и превосходит) utf8. Лучше, чтобы ваш сервер по умолчанию был utf8mb4. Популярный вариант использования utf8mb4 — смайлики.

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

Я думаю, что могло произойти следующее (это предположение).

  1. Ваши таблицы/столбцы были установлены как UTF-8.
  2. Клиент подключается и сообщает серверу: «Вместо этого я хочу использовать ISO-8559-1/latin».
  3. Сервер с радостью соответствует требованиям и на лету преобразует клиентские строки ISO-8559-1 в UTF-8.
  4. Несмотря на то, что клиент хочет использовать ISO-8559-1, он фактически отправляет кодировку UTF-8.
  5. Сервер считает, что это данные ISO-8559-1, и обрабатывает их как таковые, а затем преобразует UTF-8, используя ISO-8559-1, в UTF. Это фактически двойное кодирование.

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

Если это верно, этот процесс обратим

Вам действительно нужна обратная операция. Например, если у вас есть строка PHP $data, которая дважды закодирована как UTF-8, процесс будет просто вызывать это:

$output = utf8_decode($input)

Это также можно исправить в MySQL. См. этот вопрос о переполнении стека.

Несколько вещей, о которых следует знать:

  1. Убедитесь, что это действительно так. Получаете ли вы правильный результат после этой операции?
  2. Делайте бэкапы, понятное дело.
  3. Также убедитесь, что все, что записывало двойную кодировку UTF-8 в вашу базу данных, теперь исправлено. Последнее, что вам нужно, это таблица, представляющая собой смесь разных кодировок.

Примечание: эта проблема чрезвычайно распространена. Вам несколько повезло, что вы француз, потому что это подчеркивает проблему. Многие английские системы, которые я видел, имеют эту проблему, но в основном она остается незамеченной в течение длительного времени, потому что большая часть текста не выходит за пределы общего диапазона ASCII.

person Evert    schedule 21.09.2018
comment
Спасибо за вашу помощь. Но что это значит? Что содержимое базы данных на сервере плохое, и я ничего не могу сделать, чтобы это исправить? Почему phpMyAdmin и HeidiSQL, установленные на сервере, отображают базу данных с допустимыми символами? Мне кажется, что содержимое и настройка удаленного сервера в порядке, но то, как я экспортирую данные, а затем импортирую их на мой локально настроенный сервер MySQL, плохо. - person jpo38; 21.09.2018
comment
@ jpo38 нет, он не поврежден. Процесс обратим. Я добавил больше информации в свой ответ - person Evert; 21.09.2018
comment
Запустил команду из другого вопроса SO. Получил предупреждения о том, что «Предупреждение: недопустимая строка символов utf8:« E0206D »»... затем строки обрезаются, когда у меня был моджибаке ... так что, по-видимому, это не решает проблему. - person jpo38; 21.09.2018
comment
Смотрите мой ответ, видимо, это была проблема с обнаружением кодировки при импорте. - person jpo38; 21.09.2018

У вас есть "Моджибаке". à превращается в Ã (символов два, второй пробел).

Это происходит, когда latin1 где-то участвует в процессе. Настройки SESSION и GLOBAL не виноваты. Посмотрим SHOW CREATE TABLE.

См. Mojibake в Проблемы с UTF-8 символы; то, что я вижу, не то, что я сохранил по вероятным причинам. Это может включать «двойное кодирование»; давайте посмотрим SELECT col, HEX(col) ....

Что касается исправления данных - это зависит от того, есть ли у вас просто Mojibake или Double Encoding. См. http://mysql.rjweb.org/doc.php/charcoll#fixes_for_various_cases для обоих.

person Rick James    schedule 30.09.2018
comment
Спасибо за вашу помощь. Как сказано в моем собственном ответе, это была просто проблема с кодировкой при выполнении файла SQL для импорта базы данных в MySQL. - person jpo38; 30.09.2018
comment
@ jpo38 - я только что добавил к своему ответу два метода исправления данных. - person Rick James; 30.09.2018