Този проблем измъчва участниците в този сайт и много други.
Вие изброихте петте основни случая на CHARACTER SET
проблеми.
Най-добра практика
Занапред е най-добре да използвате CHARACTER SET utf8mb4
и COLLATION utf8mb4_unicode_520_ci
. (Има по-нова версия на съпоставянето на Unicode в процес на изпълнение.)
utf8mb4
е надмножество на utf8
тъй като обработва 4-байтови utf8 кодове, които са необходими на Emoji и някои от китайските.
Извън MySQL, "UTF-8" се отнася до кодирането на всички размери, следователно на практика същото като utf8mb4
на MySQL , а не 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
.
Коригиране на данните, където е възможно
За Отрязване и Въпросителни знаци , данните се губят.
За Моджибеке / Двойно кодиране , ...
Зачерни диаманти , ...
Поправките са изброени тук. (5 различни поправки за 5 различни ситуации; изберете внимателно):http://mysql. rjweb.org/doc.php/charcoll#fixes_for_various_cases