Mysql
 sql >> Baza danych >  >> RDS >> Mysql

Problem ze znakami UTF-8; to, co widzę, nie jest tym, co zapisałem

Ten problem nęka uczestników tej witryny i wielu innych.

Wymieniłeś pięć głównych przypadków CHARACTER SET kłopoty.

Najlepsze praktyki

Idąc dalej, najlepiej jest użyć CHARACTER SET utf8mb4 i COLLATION utf8mb4_unicode_520_ci . (W potoku jest nowsza wersja sortowania Unicode.)

utf8mb4 jest nadzbiorem utf8 w tym, że obsługuje 4-bajtowe kody utf8, które są potrzebne dla Emoji i niektórych chińskich.

Poza MySQL, „UTF-8” odnosi się do wszystkich kodowań rozmiaru, a więc w praktyce jest tożsame z utf8mb4 MySQL , a nie utf8 .

W dalszej części spróbuję użyć tej pisowni i wielkich liter, aby odróżnić MySQL od środka MySQL.

Omówienie tego, co powinieneś zrobić

  • Ustaw edytor itp. na UTF-8.
  • Formularze HTML powinny zaczynać się tak jak <form accept-charset="UTF-8"> .
  • Zakoduj swoje bajty jako UTF-8.
  • Ustal UTF-8 jako kodowanie używane w kliencie.
  • Zadeklarować kolumnę/tablicę CHARACTER SET utf8mb4 (Sprawdź za pomocą SHOW CREATE TABLE .)
  • <meta charset=UTF-8> na początku HTML
  • Przechowywane procedury pobierają bieżący zestaw znaków/porównanie. Mogą potrzebować odbudowy.

UTF- 8 przez całą drogę

Więcej informacji o językach komputerowych (i jego kolejne sekcje)

Przetestuj dane

Przeglądanie danych za pomocą narzędzia lub SELECT nie można ufać.Zbyt wielu takich klientów, zwłaszcza przeglądarek, spróbuj zrekompensować nieprawidłowe kodowanie i pokaż poprawny tekst, nawet jeśli baza danych jest zniekształcona. Wybierz więc tabelę i kolumnę, które zawierają tekst inny niż angielski i zrób to

SELECT col, HEX(col) FROM tbl WHERE ...

HEX dla poprawnie zapisanego UTF-8 to

  • Dla pustego miejsca (w dowolnym języku):20
  • W języku angielskim:4x , 5x , 6x lub 7x
  • W większości krajów Europy Zachodniej litery akcentowane powinny mieć postać Cxyy
  • Cyrylica, hebrajski i perski/arabski:Dxyy
  • Większość Azji:Exyyzz
  • Emoji i niektóre chińskie:F0yyzzww
  • Więcej szczegółów

Konkretne przyczyny i rozwiązania zauważonych problemów

Skrócony tekst (Se dla Señor ):

  • Bajty do przechowywania nie są zakodowane jako utf8mb4. Napraw to.
  • Sprawdź również, czy połączenie podczas odczytu to UTF-8.

Czarne diamenty ze znakami zapytania (Se�or dla Señor );istnieje jeden z tych przypadków:

Przypadek 1 (oryginalne bajty nie .) UTF-8):

  • Bajty do przechowywania nie są zakodowane jako utf8. Napraw to.
  • Połączenie (lub SET NAMES ) dla INSERT i SELECT nie był utf8/utf8mb4. Napraw to.
  • Sprawdź również, czy kolumna w bazie danych to CHARACTER SET utf8 (lub utf8mb4).

Przypadek 2 (oryginalne bajty były UTF-8):

  • Połączenie (lub SET NAMES ) dla SELECT nie był utf8/utf8mb4. Napraw to.
  • Sprawdź również, czy kolumna w bazie danych to CHARACTER SET utf8 (lub utf8mb4).

Czarne romby występują tylko wtedy, gdy przeglądarka jest ustawiona na <meta charset=UTF-8> .

Znaki zapytania (zwykłe, nie czarne romby) (Se?or dla Señor ):

  • Bajty do przechowywania nie są zakodowane jako utf8/utf8mb4. Napraw to.
  • Kolumna w bazie danych to nie CHARACTER SET utf8 (lub utf8mb4). Napraw to. (Użyj SHOW CREATE TABLE .)
  • Sprawdź również, czy połączenie podczas odczytu to UTF-8.

Mojibake (Señor dla Señor ):(Ta dyskusja dotyczy również podwójnego kodowania , co niekoniecznie jest widoczne.)

  • Bajty, które mają być przechowywane, muszą być zakodowane w UTF-8. Napraw to.
  • Połączenie podczas INSERTing i SELECTing tekst musi określać utf8 lub utf8mb4. Napraw to.
  • Kolumna musi być zadeklarowana CHARACTER SET utf8 (lub utf8mb4). Napraw to.
  • HTML powinien zaczynać się od <meta charset=UTF-8> .

Jeśli dane wyglądają na poprawne, ale nie zostaną poprawnie posortowane, oznacza to, że nie wybrałeś niewłaściwego sortowania, nie ma sortowania odpowiadającego Twoim potrzebom lub masz podwójne kodowanie .

Podwójne kodowanie można potwierdzić, wykonując SELECT .. HEX .. opisane powyżej.

é should come back C3A9, but instead shows C383C2A9
The Emoji 👽 should come back F09F91BD, but comes back C3B0C5B8E28098C2BD

Oznacza to, że kod szesnastkowy jest około dwa razy dłuższy niż powinien. Jest to spowodowane konwersją z latin1 (lub czegokolwiek) na utf8, a następnie traktowaniem tych bajtów tak, jakby były latin1 i powtarzaniem konwersji. Sortowanie (i porównywanie) nie działają poprawnie, ponieważ na przykład sortuje tak, jakby ciąg był Señor .

Naprawianie danych, jeśli to możliwe

Do Obcinania i Znaki zapytania , dane zostaną utracone.

Dla Mojibake / Podwójne kodowanie , ...

Dla Czarnych Diamentów , ...

Poprawki są wymienione tutaj. (5 różnych poprawek dla 5 różnych sytuacji; wybierz uważnie):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. PolyScale.ai — skalowanie MySQL i PostgreSQL z globalnym buforowaniem

  2. Wyodrębnianie podciągów MySQL za pomocą separatora

  3. Instalacja i konfiguracja MySQL na Ubuntu 20.04

  4. Zamiana wartości kolumn w MySQL

  5. JSON_QUOTE() – Jak uciec od znaków w ciągach używanych jako wartości JSON w MySQL