sql >> Database teknologi >  >> RDS >> Mysql

Problemer med UTF-8-tegn; det, jeg ser, er ikke det, jeg har gemt

Dette problem plager deltagerne på dette websted og mange andre.

Du har angivet de fem hovedtilfælde af CHARACTER SET problemer.

Bedste praksis

Fremover er det bedst at bruge CHARACTER SET utf8mb4 og COLLATION utf8mb4_unicode_520_ci . (Der er en nyere version af Unicode-sorteringen i pipelinen.)

utf8mb4 er et supersæt af utf8 ved at den håndterer 4-byte utf8-koder, som er nødvendige for Emoji og nogle kinesiske.

Uden for MySQL refererer "UTF-8" til alle størrelseskodninger, og dermed i praksis det samme som MySQL's utf8mb4 , ikke utf8 .

Jeg vil prøve at bruge disse stavemåder og store bogstaver til at skelne inde og uden for MySQL i det følgende.

Oversigt over, hvad du skal gør

  • Få din editor osv. indstillet til UTF-8.
  • HTML-formularer skal starte som <form accept-charset="UTF-8"> .
  • Få dine bytes kodet som UTF-8.
  • Etabler UTF-8 som den kodning, der bruges i klienten.
  • Få kolonnen/tabellen erklæret CHARACTER SET utf8mb4 (Tjek med SHOW CREATE TABLE .)
  • <meta charset=UTF-8> i begyndelsen af ​​HTML
  • Gemmede rutiner henter det aktuelle tegnsæt/sortering. De skal muligvis genopbygges.

UTF- 8 hele vejen igennem

Flere oplysninger om computersprog (og dets følgende afsnit)

Test dataene

Visning af data med et værktøj eller med SELECT kan ikke stole på. Alt for mange sådanne klienter, især browsere, forsøger at kompensere for forkerte kodninger og vise dig korrekt tekst, selvom databasen er ødelagt. Så vælg en tabel og kolonne, der har noget ikke-engelsk tekst og gør

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

HEX for korrekt gemt UTF-8 vil være

  • For et tomt felt (på ethvert sprog):20
  • For engelsk:4x , 5x , 6x eller 7x
  • For det meste af Vesteuropa skal bogstaver med accent være Cxyy
  • Kyrillisk, hebraisk og farsi/arabisk:Dxyy
  • Det meste af Asien:Exyyzz
  • Emoji og nogle kinesiske:F0yyzzww
  • Flere oplysninger

Specifikke årsager og rettelser af de problemer, der er set

Trunkeret tekst (Se for Señor ):

  • De bytes, der skal lagres, er ikke kodet som utf8mb4. Løs dette.
  • Tjek også, at forbindelsen under læsning er UTF-8.

Sorte diamanter med spørgsmålstegn (Se�or for Señor );en af ​​disse tilfælde eksisterer:

Tilfælde 1 (oprindelige bytes var ikke UTF-8):

  • De bytes, der skal lagres, er ikke kodet som utf8. Løs dette.
  • Forbindelsen (eller SET NAMES ) for INSERTing og SELECT var ikke utf8/utf8mb4. Løs dette.
  • Tjek også, at kolonnen i databasen er CHARACTER SET utf8 (eller utf8mb4).

Tilfælde 2 (oprindelige bytes var UTF-8):

  • Forbindelsen (eller SET NAMES ) for SELECT var ikke utf8/utf8mb4. Løs dette.
  • Tjek også, at kolonnen i databasen er CHARACTER SET utf8 (eller utf8mb4).

Sorte diamanter forekommer kun, når browseren er indstillet til <meta charset=UTF-8> .

Spørgsmålstegn (almindelige, ikke sorte diamanter) (Se?or for Señor ):

  • De bytes, der skal lagres, er ikke kodet som utf8/utf8mb4. Løs dette.
  • Kolonnen i databasen er ikke CHARACTER SET utf8 (eller utf8mb4). Løs dette. (Brug SHOW CREATE TABLE .)
  • Tjek også, at forbindelsen under læsning er UTF-8.

Mojibake (Señor for Señor ):(Denne diskussion gælder også for Dobbeltkodning , hvilket ikke nødvendigvis er synligt.)

  • De bytes, der skal lagres, skal være UTF-8-kodede. Løs dette.
  • Forbindelsen ved INSERTing og SELECTing tekst skal angive utf8 eller utf8mb4. Løs dette.
  • Kolonnen skal erklæres CHARACTER SET utf8 (eller utf8mb4). Løs dette.
  • HTML skal starte med <meta charset=UTF-8> .

Hvis dataene ser korrekte ud, men ikke vil sortere korrekt, har du hverken valgt den forkerte sortering, eller der er ingen sortering, der passer til dit behov, eller du har dobbeltkodning .

Dobbeltkodning kan bekræftes ved at udføre SELECT .. HEX .. beskrevet ovenfor.

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

Det vil sige, at hex er cirka dobbelt så lang, som den burde være. Dette skyldes konvertering fra latin1 (eller hvad som helst) til utf8, derefter behandle disse bytes, som om de var latin1 og gentage konverteringen. Sorteringen (og sammenligningen) gør det ikke fungerer korrekt, fordi den f.eks. sorterer, som om strengen var Señor .

Rettelse af dataene, hvor det er muligt

Til Trunkering og Spørgsmålstegn , går dataene tabt.

Til Mojibake / Dobbeltkodning , ...

Til Sorte diamanter , ...

rettelserne er opført her. (5 forskellige rettelser til 5 forskellige situationer; vælg omhyggeligt):http://mysql. rjweb.org/doc.php/charcoll#fixes_for_various_cases



  1. Sådan får du det korte månedsnavn fra en dato i MySQL

  2. Sådan aktiveres langsomme forespørgselslogfiler i AWS RDS MySQL

  3. Opbygning af en simpel webapp med Bottle, SQLAlchemy og Twitter API

  4. Hvordan dræber du alle nuværende forbindelser til en SQL Server 2005-database?