sql >> Databasteknik >  >> RDS >> Mysql

Problem med UTF-8-tecken; det jag ser är inte det jag har lagrat

Detta problem plågar deltagarna på den här webbplatsen och många andra.

Du har listat de fem huvudsakliga fallen av CHARACTER SET problem.

Bästa tillvägagångssätt

Framöver är det bäst att använda CHARACTER SET utf8mb4 och COLLATION utf8mb4_unicode_520_ci . (Det finns en nyare version av Unicode-sorteringen på gång.)

utf8mb4 är en superuppsättning av utf8 genom att den hanterar 4-byte utf8-koder, som behövs av Emoji och vissa kinesiska.

Utanför MySQL hänvisar "UTF-8" till alla storlekskodningar, alltså i praktiken samma som MySQL:s utf8mb4 , inte utf8 .

Jag kommer att försöka använda dessa stavningar och versaler för att skilja inuti och utanför MySQL i det följande.

Översikt över vad du bör gör

  • Få din editor etc. inställd på UTF-8.
  • HTML-formulär bör börja som <form accept-charset="UTF-8"> .
  • Ha dina bytes kodade som UTF-8.
  • Etablera UTF-8 som den kodning som används i klienten.
  • Få kolumnen/tabellen deklarerad CHARACTER SET utf8mb4 (Kontrollera med SHOW CREATE TABLE .)
  • <meta charset=UTF-8> i början av HTML
  • Lagrade rutiner hämtar den aktuella teckenuppsättningen/sorteringen. De kan behöva byggas om.

UTF- 8 hela vägen

Mer information om datorspråk (och dess följande avsnitt)

Testa data

Visa data med ett verktyg eller med SELECT går inte att lita på. Alltför många sådana klienter, särskilt webbläsare, försöker kompensera för felaktiga kodningar och visa dig korrekt text även om databasen är skadad. Så välj en tabell och kolumn som har lite icke-engelsk text och gör

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

HEX för korrekt lagrad UTF-8 kommer att vara

  • För ett tomt utrymme (på valfritt språk):20
  • För engelska:4x , 5x , 6x , eller 7x
  • För större delen av Västeuropa bör bokstäver med accent vara Cxyy
  • kyrilliska, hebreiska och farsi/arabiska:Dxyy
  • Större delen av Asien:Exyyzz
  • Emoji och lite kinesiska:F0yyzzww
  • Mer information

Särskilda orsaker och korrigeringar av de problem som uppstått

Trunkerad text (Se för Señor ):

  • Byten som ska lagras är inte kodade som utf8mb4. Åtgärda detta.
  • Kontrollera även att anslutningen under läsning är UTF-8.

Svarta diamanter med frågetecken (Se�or för Señor );ett av dessa fall finns:

Fall 1 (originalbyte var inte UTF-8):

  • Byten som ska lagras är inte kodade som utf8. Åtgärda detta.
  • Anslutningen (eller SET NAMES ) för INSERTing och SELECT var inte utf8/utf8mb4. Åtgärda detta.
  • Kontrollera även att kolumnen i databasen är CHARACTER SET utf8 (eller utf8mb4).

Fall 2 (ursprungliga bytes var UTF-8):

  • Anslutningen (eller SET NAMES ) för SELECT var inte utf8/utf8mb4. Åtgärda detta.
  • Kontrollera även att kolumnen i databasen är CHARACTER SET utf8 (eller utf8mb4).

Svarta romber förekommer endast när webbläsaren är inställd på <meta charset=UTF-8> .

Frågetecken (vanliga, inte svarta diamanter) (Se?or för Señor ):

  • Byten som ska lagras är inte kodade som utf8/utf8mb4. Åtgärda detta.
  • Kolumnen i databasen är inte CHARACTER SET utf8 (eller utf8mb4). Fixa det här. (Använd SHOW CREATE TABLE .)
  • Kontrollera även att anslutningen under läsning är UTF-8.

Mojibake (Señor för Señor ):(Denna diskussion gäller även dubbelkodning , vilket inte nödvändigtvis är synligt.)

  • Byten som ska lagras måste vara UTF-8-kodad. Åtgärda detta.
  • Anslutningen vid INSERTing och SELECTing text måste ange utf8 eller utf8mb4. Åtgärda detta.
  • Kolumnen måste deklareras CHARACTER SET utf8 (eller utf8mb4). Åtgärda detta.
  • HTML bör börja med <meta charset=UTF-8> .

Om uppgifterna ser korrekta ut, men inte sorteras korrekt, har du inte valt fel sortering, eller så finns det ingen sortering som passar ditt behov, eller så har du dubbelkodning .

Dubbelkodning kan bekräftas genom att göra SELECT .. HEX .. beskrivs ovan.

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

Det vill säga, hexen är ungefär dubbelt så lång som den borde vara. Detta orsakas av att konvertera från latin1 (eller vad som helst) till utf8, sedan behandla dessa byte som om de vore latin1 och upprepa konverteringen. Sorteringen (och jämförelsen) gör det inte fungerar korrekt eftersom det till exempel sorterar som om strängen vore Señor .

Åtgärda data, där det är möjligt

För Trunkering och Frågetecken , data går förlorade.

För Mojibake / Dubbelkodning , ...

För svarta diamanter , ...

Åtgärderna är listade här. (5 olika korrigeringar för 5 olika situationer; välj noga):http://mysql. rjweb.org/doc.php/charcoll#fixes_for_various_cases



  1. Dela upp stor text/CSV-fil i flera filer i PL SQL

  2. Förstå DROP TABLE-satsen i SQL Server

  3. Flytta SQL-data från en tabell till en annan

  4. Hur ändrar jag formateringen för mina returvärden i den här funktionen?