Този проблем измъчва участниците в този сайт и много други.
Вие изброихте петте основни случая на 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 различни ситуации; изберете внимателно):https://mysql. rjweb.org/doc.php/charcoll#fixes_for_various_cases