Ответ 1
Эта проблема преследует участников этого сайта и многих других.
Вы перечислили пять основных случаев проблем 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- Сохраненные процедуры получают текущий набор символов/сопоставлений. Они могут нуждаться в восстановлении.
Подробнее о компьютерных языках (и следующих разделах)
Проверьте данные
Просмотр данных с помощью инструмента или с помощью SELECT
не может быть доверенным.
Слишком много таких клиентов, особенно браузеров, пытаются компенсировать неправильные кодировки и показывают правильный текст, даже если база данных искажена.
Итак, выберите таблицу и столбец с неанглийским текстом и выполните
SELECT col, HEX(col) FROM tbl WHERE ...
HEX для правильно сохраненного UTF-8 будет
- Для пробела (на любом языке):
20
- Для английского языка:
4x
,5x
,6x
или7x
- Для большинства стран Западной Европы буквы с акцентом должны быть
Cxyy
- Кириллица, иврит и фарси/арабский:
Dxyy
- Большая часть Азии:
Exyyzz
- Эмодзи и некоторые из китайцев:
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.
Моджибаке (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
.
Исправление данных, где это возможно
Для усечения и знаков вопроса данные теряются.
Для моджибаке/двойного кодирования,...
Для черных бриллиантов,...
(Я должен продолжить это в другом вопросе/ответе.)