Три места, где у MySQL есть кодировка
- Столбец или таблица: кодировка хранения данных, например
utf8mb4илиcp1251. - Соединение: кодировка, на которой клиент и сервер общаются. Задаётся командой
SET NAMES utf8mb4или в настройках подключения. - Файл: кодировка, в которой читается импорт и пишется экспорт. В phpMyAdmin это пункт Кодировка файла (Character set of the file).
Если эти три места не совпадают, буквы ломаются. Типичный случай: сайт в UTF-8 пишет в таблицу по соединению latin1 или cp1251. На сайте всё выглядит нормально, а phpMyAdmin и дамп показывают Привет или Привет.
До
"1","Олег Петров","ул. Ленина, 12","Нижний Новгород"
После
"1","Олег Петров","ул. Ленина, 12","Нижний Новгород"
Проверяем кодировки
SHOW VARIABLES LIKE 'character_set%';покажет настройки сервера и соединения.SHOW CREATE TABLE customers;покажет кодировку таблицы и её столбцов.SELECT name, HEX(name) FROM customers LIMIT 5;покажет реальные байты. В столбцеutf8mb4буква «П» хранится какD09F, а уже испорченная, дважды закодированная — какC390C29F.
Исправляем выгрузку или дамп
- Выгрузите таблицу из phpMyAdmin в SQL или CSV либо выполните
mysqldump --default-character-set=utf8mb4. - Перетащите файл в поле выше. Mojibuster исправит только испорченные места, правильный текст не изменится.
- Посмотрите исправления в разделе Что изменилось? и скачайте файл.
- Импортируйте его в таблицу с
utf8mb4и выберите в окне импорта кодировкуutf-8. - Сначала проверьте всё на копии, а потом заменяйте настоящую таблицу.
Выгрузка не покидает ваш компьютер, а это важно для данных клиентов. Если файл сохранён в Windows-1251, Mojibuster определит это сам и сохранит его в UTF-8. Подробнее о таких файлах: Windows-1251 в UTF-8.
Устраняем причину
- Создавайте таблицы с
DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci. - Выставьте
utf8mb4в соединении приложения. В PHP, например, добавьтеcharset=utf8mb4в DSN для PDO. - Если в столбце
cp1251илиlatin1лежат байты UTF-8, не конвертируйте его напрямую черезCONVERT TO: текст закодируется второй раз. Безопасный путь идёт через двоичный тип: сначалаMODIFY name VARBINARY(255), затемMODIFY name VARCHAR(255) CHARACTER SET utf8mb4. - Если MySQL заменил буквы знаками
?, столбец или соединение не умеют их хранить. То, что уже записано так, потеряно. Об этом подробно написано в статье что такое кракозябры.
Частые вопросы
Почему на сайте всё нормально, а в phpMyAdmin кракозябры?
Сайт и база ошибаются одинаково дважды: сайт пишет UTF-8 по соединению latin1 и так же читает обратно. phpMyAdmin подключается правильно и поэтому показывает то, что реально хранится. Если кракозябры возникли после переноса сайта, смотрите также про WordPress и базы данных и двойную кодировку.
Какую сортировку (collation) выбрать?
Для большинства сайтов подойдёт utf8mb4_unicode_ci, а в MySQL 8 по умолчанию стоит utf8mb4_0900_ai_ci. Важнее кодировка utf8mb4, а не utf8: в MySQL она не хранит эмодзи.
Работает ли это с MariaDB?
Да. MariaDB работает с кодировками так же, как MySQL, и команды те же.
Какого размера может быть дамп?
До 100 МБ на файл. Большие базы выгружайте по таблицам.