sql >> Database >  >> RDS >> Mysql

Problemen met UTF-8-tekens; wat ik zie is niet wat ik heb opgeslagen

Dit probleem plaagt de deelnemers van deze site, en vele anderen.

Je hebt de vijf belangrijkste gevallen van CHARACTER SET . opgesomd problemen.

Beste praktijken

In de toekomst is het het beste om CHARACTER SET utf8mb4 . te gebruiken en COLLATION utf8mb4_unicode_520_ci . (Er is een nieuwere versie van de Unicode-sortering in de pijplijn.)

utf8mb4 is een superset van utf8 in die zin dat het 4-byte utf8-codes verwerkt, die nodig zijn voor Emoji en sommige Chinese.

Buiten MySQL verwijst "UTF-8" naar alle groottecoderingen, dus in feite hetzelfde als MySQL's utf8mb4 , niet utf8 .

Ik zal proberen die spelling en hoofdletters te gebruiken om onderscheid te maken tussen binnen en buiten MySQL in het volgende.

Overzicht van wat u moet doen

  • Laat je editor, enz. op UTF-8 staan.
  • HTML-formulieren moeten beginnen als <form accept-charset="UTF-8"> .
  • Laat uw bytes coderen als UTF-8.
  • Stel UTF-8 in als de codering die in de client wordt gebruikt.
  • Laat de kolom/tabel gedeclareerd CHARACTER SET utf8mb4 (Controleer met SHOW CREATE TABLE .)
  • <meta charset=UTF-8> aan het begin van HTML
  • Opgeslagen routines verkrijgen de huidige tekenset/sortering. Ze moeten mogelijk opnieuw worden opgebouwd.

UTF- 8 helemaal door

Meer details voor computertalen (en de volgende secties)

Test de gegevens

De gegevens bekijken met een tool of met SELECT kan niet worden vertrouwd. Te veel van dergelijke clients, vooral browsers, proberen onjuiste coderingen te compenseren en u correcte tekst te laten zien, zelfs als de database is verminkt. Kies dus een tabel en kolom met niet-Engelse tekst en doe dat

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

De HEX voor correct opgeslagen UTF-8 is

  • Voor een spatie (in elke taal):20
  • Voor Engels:4x , 5x , 6x , of 7x
  • Voor het grootste deel van West-Europa moeten letters met accenten Cxyy zijn
  • Cyrillisch, Hebreeuws en Farsi/Arabisch:Dxyy
  • Het grootste deel van Azië:Exyyzz
  • Emoji en wat Chinees:F0yyzzww
  • Meer details

Specifieke oorzaken en oplossingen van de waargenomen problemen

Afgekapt tekst (Se voor Señor ):

  • De op te slaan bytes zijn niet gecodeerd als utf8mb4. Los dit op.
  • Controleer ook of de verbinding tijdens het lezen UTF-8 is.

Zwarte diamanten met vraagtekens (Se�or voor Señor );een van deze gevallen bestaat:

Geval 1 (oorspronkelijke bytes waren niet UTF-8):

  • De op te slaan bytes zijn niet gecodeerd als utf8. Los dit op.
  • De verbinding (of SET NAMES ) voor de INSERT en de SELECT was niet utf8/utf8mb4. Los dit op.
  • Controleer ook of de kolom in de database CHARACTER SET utf8 is (of utf8mb4).

Geval 2 (oorspronkelijke bytes waren UTF-8):

  • De verbinding (of SET NAMES ) voor de SELECT was niet utf8/utf8mb4. Los dit op.
  • Controleer ook of de kolom in de database CHARACTER SET utf8 is (of utf8mb4).

Zwarte diamanten komen alleen voor als de browser is ingesteld op <meta charset=UTF-8> .

Vraagtekens (gewone, geen zwarte diamanten) (Se?or voor Señor ):

  • De op te slaan bytes zijn niet gecodeerd als utf8/utf8mb4. Los dit op.
  • De kolom in de database is niet CHARACTER SET utf8 (of utf8mb4). Repareer dit. (Gebruik SHOW CREATE TABLE .)
  • Controleer ook of de verbinding tijdens het lezen UTF-8 is.

Mojibake (Señor voor Señor ):(Deze discussie is ook van toepassing op Double Encoding , wat niet per se zichtbaar is.)

  • De op te slaan bytes moeten UTF-8-gecodeerd zijn. Los dit op.
  • De verbinding bij INSERTing en SELECTing tekst moet utf8 of utf8mb4 specificeren. Los dit op.
  • De kolom moet worden gedeclareerd CHARACTER SET utf8 (of utf8mb4). Los dit op.
  • HTML moet beginnen met <meta charset=UTF-8> .

Als de gegevens er correct uitzien, maar niet correct worden gesorteerd, heeft u ofwel de verkeerde sortering gekozen, ofwel is er geen sortering die aan uw behoeften voldoet, ofwel heeft u Double Encoding .

Dubbele codering kan worden bevestigd door de SELECT .. HEX .. hierboven beschreven.

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

Dat wil zeggen, de hex is ongeveer twee keer zo lang als het zou moeten zijn. Dit wordt veroorzaakt door het converteren van latin1 (of wat dan ook) naar utf8, die bytes vervolgens te behandelen alsof ze latin1 zijn en de conversie te herhalen. Het sorteren (en vergelijken) doet dat niet correct werken omdat het bijvoorbeeld sorteert alsof de string Señor . is .

De gegevens corrigeren, waar mogelijk

Voor Truncatie en Vraagtekens , de gegevens gaan verloren.

Voor Mojibake / Dubbele codering , ...

Voor Zwarte Diamanten , ...

De Oplossingen worden hier vermeld. (5 verschillende oplossingen voor 5 verschillende situaties; kies zorgvuldig):http://mysql. rjweb.org/doc.php/charcoll#fixes_for_various_cases



  1. MySQL Galera-cluster herstellen van een asynchrone slaaf

  2. PL/SQL-opgeslagen procedures maken met parameters in Oracle Database?

  3. Achterwaartse scan van SQL Server-index:begrijpen, afstemmen

  4. Exporteer SQL-querygegevens naar Excel