Три місця, де в 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 МБ на файл. Великі бази вивантажуйте по таблицях.