Ця проблема мучить учасників цього сайту та багатьох інших.
Ви перерахували п’ять основних випадків CHARACTER SET
неприємностей.
Найкраща практика
Забігаючи вперед, найкраще використовувати CHARACTER SET utf8mb4
і COLLATION utf8mb4_unicode_520_ci
. (У конвеєрі є нова версія версії Unicode).
utf8mb4
є надмножиною того, utf8
що він обробляє 4-байтові коди utf8, які потрібні Emoji та деяким китайцям.
За межами MySQL, "UTF-8" відноситься до всіх кодувань розмірів, отже, фактично збігається з кодуванням MySQL utf8mb4
, а не utf8
.
Я спробую використовувати ці орфографії та великі літери, щоб розрізнити всередині та поза MySQL у наступному.
Огляд того, що ви повинні робити
- Нехай ваш редактор тощо буде встановлений на UTF-8.
- Форми HTML повинні починатися як
<form accept-charset="UTF-8">
.
- Нехай ваші байти закодуються як UTF-8.
- Встановіть UTF-8 як кодування, яке використовується в клієнті.
- Є стовпець / таблиця оголошена
CHARACTER SET utf8mb4
(перевірте SHOW CREATE TABLE
) .
<meta charset=UTF-8>
на початку HTML
- Збережені підпрограми отримують поточну кодировку / порівняння. Можливо, їм знадобиться відбудова.
UTF-8 до кінця
Докладніше про комп’ютерні мови (та наступні розділи)
Перевірте дані
Перегляд даних за допомогою інструменту або за SELECT
допомогою не можна довіряти. Занадто багато таких клієнтів, особливо браузерів, намагаються компенсувати неправильне кодування та показують правильний текст, навіть якщо база даних перекручена. Отже, виберіть таблицю та стовпець, що містить текст, який не є англійською мовою, і виконайте
SELECT col, HEX(col) FROM tbl WHERE ...
Буде HEX для правильно збереженого UTF-8
- Для пробілу (будь-якою мовою):
20
- Для англійської мови:
4x
, 5x
, 6x
, або7x
- Для більшості країн Західної Європи букви з наголосом мають бути
Cxyy
- Кирилиця, іврит та фарсі / арабська:
Dxyy
- Більша частина Азії:
Exyyzz
- Emoji та деякі китайські:
F0yyzzww
- Детальніше
Конкретні причини та способи усунення побачених проблем
Зрізаний текст ( Se
для Señor
):
- Байти, що зберігаються, не кодуються як utf8mb4. Виправте це.
- Також перевірте, чи підключено під час читання UTF-8.
Чорні діаманти зі знаками запитання ( Se�or
для Señor
); існує один із таких випадків:
Випадок 1 (оригінальні байти не були UTF-8):
- Байти, що зберігаються, не кодуються як utf8. Виправте це.
- З'єднання (або
SET NAMES
) для INSERT
іSELECT
НЕ utf8 / utf8mb4. Виправте це.
- Також перевірте, чи стовпець у базі даних
CHARACTER SET utf8
(або utf8mb4).
Випадок 2 (оригінальними байтами були UTF-8):
- З'єднання (або
SET NAMES
) для SELECT
не було utf8 / utf8mb4. Виправте це.
- Також перевірте, чи стовпець у базі даних
CHARACTER SET utf8
(або utf8mb4).
Чорні діаманти трапляються лише тоді, коли для браузера встановлено значення <meta charset=UTF-8>
.
Знаки питання (звичайні, а не чорні діаманти) ( Se?or
для Señor
):
- Байти, що зберігаються, не кодуються як utf8 / utf8mb4. Виправте це.
- Стовпець у базі даних не є
CHARACTER SET utf8
(або utf8mb4). Виправте це. (Використовуйте SHOW CREATE TABLE
.)
- Також перевірте, чи підключено під час читання UTF-8.
Mojibake ( Señor
для Señor
): (Це обговорення стосується також подвійного кодування , яке не обов’язково видно.)
- Байти, які слід зберегти, повинні мати кодування UTF-8. Виправте це.
- Зв'язок коли
INSERTing
і SELECTing
текст повинен вказувати utf8 або utf8mb4. Виправте це.
- Стовпець потрібно оголосити
CHARACTER SET utf8
(або utf8mb4). Виправте це.
- HTML слід починати з
<meta charset=UTF-8>
.
Якщо дані виглядають правильно, але сортувати їх не вдасться правильно, то або ви вибрали неправильний метод сортування, або не існує порівняння, яке відповідає вашим потребам, або у вас є подвійне кодування .
Подвійне кодування можна підтвердити, виконавши SELECT .. HEX ..
описане вище.
é should come back C3A9, but instead shows C383C2A9
The Emoji 👽 should come back F09F91BD, but comes back C3B0C5B8E28098C2BD
Тобто шестигранник приблизно вдвічі довший, ніж повинен бути. Це викликано перетворенням з latin1 (або будь-якого іншого) у utf8, потім обробкою цих байтів, ніби вони є latin1, і повторенням перетворення. Сортування (і порівняння) не працює належним чином, оскільки це, наприклад, сортування, ніби це рядок Señor
.
Виправлення даних, де це можливо
Для скорочення та знаків запитання дані втрачаються.
Для Mojibake / Подвійне кодування , ...
Для Black Diamonds , ...
У скрутних перераховані тут. (5 різних виправлень для 5 різних ситуацій; обережно вибирайте): http://mysql.rjweb.org/doc.php/charcoll#fixes_for_various_cases
utf8mb4
я, здається, можу зберігати смайлики чудово. Деякі блоги пропонують також встановитиcollation-server
таcharacter-set-server
в mysqld. Чи справді потрібно змінюватиmysqld
різницю в налаштуваннях сервера?