Три места, където MySQL има кодировка
- Колона или таблица: кодировката, в която се съхраняват данните, например
utf8mb4илиcp1251. - Връзка: кодировката, на която клиентът и сървърът си говорят. Задава се с
SET NAMES utf8mb4или в настройките на връзката. - Файл: кодировката, с която се чете импорт и се пише експорт. В phpMyAdmin това е Набор от знаци на файла (Character set of the file).
Ако трите места не съвпадат, буквите се чупят. Най-честият случай: сайт в UTF-8 записва текст през връзка latin1 или cp1251. В сайта всичко изглежда наред, но phpMyAdmin и експортът показват Здравей или Здравей.
Преди
"1","Здравко Йорданов","ул. Цар Борис III 12","Шумен"
След
"1","Здравко Йорданов","ул. Цар Борис III 12","Шумен"
Проверка на кодировките
SHOW VARIABLES LIKE 'character_set%';показва настройките на сървъра и връзката.SHOW CREATE TABLE customers;показва кодировката на таблицата и на колоните ѝ.SELECT name, HEX(name) FROM customers LIMIT 5;показва същинските байтове. В колонаutf8mb4буквата „З“ еD097, а вече повредената, двойно кодирана буква еC390C297.
Поправяне на експорт или дъмп
- Експортирайте таблицата от 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 е заменил буквите с
?, колоната или връзката не могат да ги съхранят. Вече записаното така е загубено. Повече в статията какво е mojibake.
Често задавани въпроси
Защо в приложението всичко е наред, а в phpMyAdmin има странни символи?
Защото приложението и базата грешат по един и същи начин два пъти: приложението записва UTF-8 през връзка latin1 и го чете обратно по същия начин. phpMyAdmin се свързва правилно и затова показва какво наистина е записано.
Коя колация да избера?
utf8mb4_unicode_ci е подходяща за повечето приложения, а от MySQL 8 по подразбиране е utf8mb4_0900_ai_ci. По-важен е наборът utf8mb4, а не utf8: той не съхранява емотикони.
Работи ли и с MariaDB?
Да. MariaDB работи с кодировките като MySQL и командите са същите.
Колко голям може да е дъмпът?
До 100 MB на файл. По-големи бази експортирайте таблица по таблица.