Dieses Problem plagt die Teilnehmer dieser Site und viele andere.
Sie haben die fünf Hauptprobleme aufgelistet CHARACTER SET
.
Beste Übung
In Zukunft ist es am besten, CHARACTER SET utf8mb4
und zu verwenden COLLATION utf8mb4_unicode_520_ci
. (Es ist eine neuere Version der Unicode-Sortierung in der Pipeline.)
utf8mb4
ist eine Obermenge davon, utf8
dass es 4-Byte-utf8-Codes verarbeitet, die von Emoji und einigen Chinesen benötigt werden.
Außerhalb von MySQL bezieht sich "UTF-8" auf alle Größencodierungen, daher praktisch die gleichen wie bei MySQL utf8mb4
, nicht utf8
.
Ich werde versuchen, diese Schreibweisen und Großschreibungen zu verwenden, um im Folgenden innerhalb und außerhalb von MySQL zu unterscheiden.
Überblick darüber, was Sie tun sollten
- Stellen Sie Ihren Editor usw. auf UTF-8 ein.
- HTML-Formulare sollten wie folgt beginnen
<form accept-charset="UTF-8">
.
- Lassen Sie Ihre Bytes als UTF-8 codieren.
- Richten Sie UTF-8 als die im Client verwendete Codierung ein.
- Lassen Sie die Spalte / Tabelle deklarieren
CHARACTER SET utf8mb4
( überprüfen mit SHOW CREATE TABLE
.)
<meta charset=UTF-8>
am Anfang von HTML
- Gespeicherte Routinen erfassen den aktuellen Zeichensatz / die aktuelle Sortierung. Sie müssen möglicherweise neu aufgebaut werden.
UTF-8 bis zum Ende
Weitere Details zu Computersprachen (und den folgenden Abschnitten)
Testen Sie die Daten
Das Anzeigen der Daten mit einem Tool oder mit SELECT
kann nicht als vertrauenswürdig eingestuft werden. Zu viele solcher Clients, insbesondere Browser, versuchen, falsche Codierungen zu kompensieren und zeigen Ihnen korrekten Text an, selbst wenn die Datenbank beschädigt ist. Wählen Sie also eine Tabelle und eine Spalte mit nicht englischem Text aus und tun Sie dies
SELECT col, HEX(col) FROM tbl WHERE ...
Das HEX für korrekt gespeichertes UTF-8 ist
- Für ein Leerzeichen (in einer beliebigen Sprache):
20
- Für Englisch:
4x
, 5x
, 6x
, oder7x
- Für den größten Teil Westeuropas sollten Buchstaben mit Akzent verwendet werden
Cxyy
- Kyrillisch, Hebräisch und Persisch / Arabisch:
Dxyy
- Der größte Teil Asiens:
Exyyzz
- Emoji und einige Chinesen:
F0yyzzww
- Mehr Details
Spezifische Ursachen und Lösungen für die aufgetretenen Probleme
Abgeschnittener Text ( Se
für Señor
):
- Die zu speichernden Bytes werden nicht als utf8mb4 codiert. Repariere das.
- Überprüfen Sie außerdem, ob die Verbindung während des Lesens UTF-8 ist.
Schwarze Diamanten mit Fragezeichen ( Se�or
für Señor
); Einer dieser Fälle liegt vor:
Fall 1 (ursprüngliche Bytes waren nicht UTF-8):
- Die zu speichernden Bytes werden nicht als utf8 codiert. Repariere das.
- Die Verbindung (oder
SET NAMES
) für das INSERT
und das SELECT
war nicht utf8 / utf8mb4. Repariere das.
- Überprüfen Sie außerdem, ob die Spalte in der Datenbank
CHARACTER SET utf8
(oder utf8mb4) lautet.
Fall 2 (ursprüngliche Bytes waren UTF-8):
- Die Verbindung (oder
SET NAMES
) für das SELECT
war nicht utf8 / utf8mb4. Repariere das.
- Überprüfen Sie außerdem, ob die Spalte in der Datenbank
CHARACTER SET utf8
(oder utf8mb4) lautet.
Schwarze Diamanten treten nur auf, wenn der Browser auf eingestellt ist <meta charset=UTF-8>
.
Fragezeichen (normale, keine schwarzen Diamanten) ( Se?or
für Señor
):
- Die zu speichernden Bytes werden nicht als utf8 / utf8mb4 codiert. Repariere das.
- Die Spalte in der Datenbank ist nicht
CHARACTER SET utf8
(oder utf8mb4). Repariere das. (Verwenden SHOW CREATE TABLE
.)
- Überprüfen Sie außerdem, ob die Verbindung während des Lesens UTF-8 ist.
Mojibake ( Señor
für Señor
): (Diese Diskussion gilt auch für die Doppelkodierung , die nicht unbedingt sichtbar ist.)
- Die zu speichernden Bytes müssen UTF-8-codiert sein. Repariere das.
- Die Verbindung wann
INSERTing
und SELECTing
Text muss utf8 oder utf8mb4 angeben. Repariere das.
- Die Spalte muss deklariert werden
CHARACTER SET utf8
(oder utf8mb4). Repariere das.
- HTML sollte mit beginnen
<meta charset=UTF-8>
.
Wenn die Daten korrekt aussehen, aber nicht korrekt sortiert werden, haben Sie entweder die falsche Sortierung ausgewählt oder es gibt keine Kollatierung, die Ihren Anforderungen entspricht, oder Sie haben die doppelte Codierung .
Die doppelte Codierung kann durch Ausführen der SELECT .. HEX ..
oben beschriebenen Schritte bestätigt werden .
é should come back C3A9, but instead shows C383C2A9
The Emoji 👽 should come back F09F91BD, but comes back C3B0C5B8E28098C2BD
Das heißt, das Hex ist ungefähr doppelt so lang wie es sein sollte. Dies wird verursacht, indem von latin1 (oder was auch immer) nach utf8 konvertiert wird, diese Bytes dann so behandelt werden, als wären sie latin1, und die Konvertierung wiederholt wird. Das Sortieren (und Vergleichen) funktioniert nicht richtig, da beispielsweise so sortiert wird, als ob die Zeichenfolge wäre Señor
.
Daten nach Möglichkeit korrigieren
Bei Kürzungen und Fragezeichen gehen die Daten verloren.
Für Mojibake / Double Encoding ...
Für schwarze Diamanten ...
Die Fixes sind hier aufgelistet. (5 verschiedene Korrekturen für 5 verschiedene Situationen; sorgfältig auswählen): http://mysql.rjweb.org/doc.php/charcoll#fixes_for_various_cases
utf8mb4
ich Emojis problemlos speichern. Einige Blogs empfehlen auch das Einstellencollation-server
undcharacter-set-server
in mysqld. Muss ich wirklich ändern,mysqld
welchen Unterschied die Servereinstellungen machen?SET NAMES utf8mb4
direkt nach dem Verbinden. Dies deklariert schließlich die Codierung im Client .utf8mb4
undutf8mb4_0900_ai_ci
. Die meisten Benutzer sollten sie verwenden, ohne die anderen Zeichensätze und Sortierungen zu berücksichtigen.FUNCTION
oderSTORED PROCEDURE
beteiligt ist, haben Sie möglicherweise nicht den gewünschten Zeichensatz verwendet, als Sie ihn erstellt haben.DROP
es ,SET NAMES
; ReCREATE
it.Nach einer Servermigration hatte ich ähnliche Probleme mit zwei meiner Projekte. Nachdem ich viele Lösungen gesucht und ausprobiert hatte, stieß ich auf diese:
Nach dem Hinzufügen dieser Zeile zu meiner Konfigurationsdatei funktioniert alles einwandfrei!
Ich habe diese Lösung für mysqli https://www.w3schools.com/PHP/func_mysqli_set_charset.asp gefunden, als ich eine Einfügung aus einer HTML-Abfrage lösen wollte
Viel Glück!
quelle
mysqli
, nichtPDO
.Lustig, wie du deine eigene Frage beantwortest :)
Stellen Sie Ihre Code-IDE-Sprache auf UTF8 ein
Fügen Sie Ihrem Webseiten-Header hinzu, in dem Sie Daten sammeln.
Überprüfen Sie, ob Ihre MySQL-Tabellendefinition folgendermaßen aussieht:
CREATE TABLE your_table ( ... ) ENGINE=InnoDB DEFAULT CHARSET=utf8
Wenn Sie PDO verwenden, stellen Sie sicher
$options = array(PDO::MYSQL_ATTR_INIT_COMMAND=>'SET NAMES utf8'); $dbL = new PDO($pdo, $user, $pass, $options);
Wenn Sie bereits eine große Datenbank mit dem oben genannten Problem haben, können Sie versuchen, SIDU mit dem richtigen Zeichensatz zu exportieren und mit UTF8 zurück zu importieren. Viel Glück
quelle
DEFAULT CHARSET
für eine Tabelle ist genau das, eine Standardeinstellung. Es kann und sollte manchmal in der Spaltendefinition überschrieben werden.$db = new PDO('dblib:host=host;dbname=db;charset=UTF8', $user, $pwd);
(Dies ist im Link zu meinem 'charcoll'-Dokument aufgeführt.)ALTER DATABASE
Anweisung erfordert keinen Neustart von MySQL, um wirksam zu werden. Das Ändern des Standardzeichensatzes für eine Datenbank wirkt sich jedoch nicht auf Tabellen aus, die sich derzeit in der Datenbank befinden. Dies wirkt sich nur auf neue Tabellen aus, z. B.CREATE TABLE
die keinen Standardzeichensatz für die Tabelle angeben. Dann kommt der Standard-Zeichensatz der Datenbank ins Spiel. (In ähnlicher Weise wirkt sich das Ändern des Standardzeichensatzes der Tabelle nicht auf Spalten aus, die bereits in der Tabelle enthalten sind.Ich suchte auch nach dem gleichen Problem. Ich brauchte fast einen Monat, um die passende Lösung zu finden. Zunächst müssen Sie Ihre Datenbank mit allen aktuellen CHARACTER und COLLATION auf utf8mb4 oder mindestens aktualisieren, die utf-8-Daten unterstützen.
Für Java:
Wenn Sie eine JDBC-Verbindung herstellen, fügen Sie diese zur Verbindungs-URL hinzu. Verwenden Sie Unicode = yes & characterEncoding = UTF-8 als Parameter, und es funktioniert.
Für Python:
Versuchen Sie vor dem Abfragen in der Datenbank, dies über den Cursor zu erzwingen *
cursor.execute('SET NAMES utf8mb4')
cursor.execute("SET CHARACTER SET utf8mb4")
cursor.execute("SET character_set_connection=utf8mb4")
*Wenn es nicht funktioniert, suchen Sie gerne nach der richtigen Lösung.
quelle
SETs
sind nicht der 'richtige' Weg für Python; siehe mysql.rjweb.org/doc.php/charcoll#python Viele andere Sprachen werden an anderer Stelle in diesem Blog behandelt.SET
Anweisungen im Grunde genommen eine Problemumgehung darstellen .Je nachdem, wie der Server eingerichtet ist, müssen Sie die Codierung entsprechend ändern. utf8 von dem, was Sie gesagt haben, sollte am besten funktionieren, aber wenn Sie seltsame Zeichen bekommen, kann es hilfreich sein, wenn Sie die Webseite Encode in Ansi ändern. Dies hat mir beim Einrichten eines PHP-MYSQLI geholfen. Dies könnte Ihnen helfen, mehr über /superuser/762473/ansi-to-utf-8-in-notepad zu erfahren
quelle
ANSI
ist wahrscheinlich MySQL's am nächstenlatin1
. Die 0x93 in diesem Link ist“
und stammt wahrscheinlich von einem Ort wie Word. Sie können entweder in utf8 (hexE2809C
) konvertieren oder MySQL mitteilen, dass die Daten vorhanden sind,latin1
und hoffen, dass Sie nicht woanders stolpern.