Mysql
 sql >> база данни >  >> RDS >> Mysql

Проблем с UTF-8 знаци; това, което виждам, не е това, което съм съхранил

Този проблем измъчва участниците в този сайт и много други.

Вие изброихте петте основни случая на 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
  • Съхранените подпрограми придобиват текущия набор от знаци/съпоставяне. Може да се нуждаят от възстановяване.

UTF- 8 докрай

Още подробности за компютърните езици (и следващите му раздели)

Тествайте данните

Преглед на данните с инструмент или с 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



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Как да проверите дали mysql база данни съществува

  2. Как да разделите низ в MySQL

  3. @GeneratedValue полиморфен абстрактен суперклас над MySQL

  4. Разрешени ли са вложени транзакции в MySQL?

  5. mysqli_stmt::bind_param():Броят на елементите в низа за дефиниране на типа не съвпада с броя на променливите за свързване