dedlfix: zeichensatz/umlaute-problem in mysql-datenbank

Beitrag lesen

Hi!

Der PMA hat damit insofern nichts zu tun, als dass er nur ein Werkzeug ist, der dir was anzeigt und Änderungen am Datenbestand vornehmen kann.
heißt das, die einstellung der felcodierung hat nur etwas mit PMA zu tun, nicht aber damit, wie die daten abgespeichert werden, wenn sie von aussen kommen? ich dachte, die werden dann ggf. umcodiert??

Der PMA ist auch nur ein PHP-Script wie jedes andere auch. Es fragt bei MySQL nach, vermutlich in den INFORMATION_SCHEMA-Tabellen, was die jeweilige Tabelle für Felder hat und wie diese konfiguriert sind. Wenn du daran was änderst, schickt er ein passendes ALTER TABLE-Statement zu MySQL.

Jetzt gehe ich doch in die Eingeweide. Üblicherweise muss man ansonsten nur wissen: Feldkodierung=utf8, SET NAMES utf8 und als Client auch wirklich UTF-8 verwenden.

Für die Clientverbindung kennt MySQL insgesamt drei Konfigurationswerte. Alle drei werden mit SET NAMES oder SET CHARACTER SET eingestellt, wenn auch gerinfügig anders (siehe Connection Character Sets and Collations.

  • character_set_results wird für die Antwort in Richtung Client verwendet. Ist die Feldkodierung eine andere, wird beim Abfragen in genau diese Kodierung umkodiert.

  • character_set_client ist die Kodierung, in der der Client die Daten sendet (senden sollte, wenn er es richtig machen will).

  • character_set_connection ist bereits für eine potentielle erste Umkodierung verantwortlich. MySQL übersetzt das was der Client geschickt hat grundsätzlich erst einmal in diese Kodierung. Wenn es dann die Daten in die Felder schreibt, wird gegebenenfalls noch einmal in die Feldkodierung umkodiert.

Der PMA setzt für sich selbst effektiv character_set_results und character_set_client auf UTF-8 und character_set_connection auf den auf der Startseite unter MySQL connection collation - Zeichensatz/Kollation der MySQL-Verbindung eingestellten Wert. Damit redet er grundsätzlich in UTF-8, lässt aber sein Gerede gegebenenfalls umkodieren, bevor es in Richtung Felder weitergeht.

Das Ganze kann man nachvollziehen, indem man sich das Query-Log von MySQL ansieht, so man administrativen Zugang dazu hat. Mit dem PMA stellt sich das wie folgt dar:

  • UTF-8 auf der PMA-Startseite einstellen
  • ein 中国 in ein UTF-8-Feld schreiben (irgendwas, das in Latin1/Windows-1252 nicht vorkommt)
  • Umstellen auf der Startseite nach Latin1
  • beim Abfragen wird das 中国 richtig angezeigt
  • ändern des 中国 in 德国
  • abgefragt sieht man ??, also (nur) 2 Fragezeichen. MySQL hat also aufgrund von character_set_client zwei UTF-8-Zeichen erkannt, diese aufgrund von character_set_connection nach Latin1 umkodieren sollen, was nicht ging, und daraus 2 Fragezeichen gemacht, die dann im Feld in der Feldkodierung (also immer noch UTF-8) gelandet sind.

also die PMA-webanzeige ist auf utf-8 gestellt, die feldcodierung auf latin1, die daten in den feldern sind aber utf8 und werden auch inkl. aller umlaute richtig dargestellt. was passiert also, wenn ich die feldcodierung auf utf8 umstelle. wird dann der utf8-inhalt nochmal umcodiert. vermutlich, wenn er eh schon utf8 ist, nicht, oder?

Generell geantwortet:
Wenn die Feldkodierung auf Latin1 steht, geht MySQL davon aus, dass die Daten darin auch so kodiert sind. Wenn du sie abfragst und sie gemäß character_set_results interpretierst, siehst du das, was auch MySQL sieht, wenn er die gespeicherten Bytes (zwecks Stringverarbeitung beispielsweise) interpretieren soll. Wenn die Daten im Feld tatsächlich UTF-8-kodiert sind, liest MySQL aufgrund der Latin1-Einstellung des Feldes für ein Ü die beiden Zeichen Ü, kodiert sie nach character_set_results um und zeigt sie dir oder dem PMA. Wenn du in dem Zustand die Feldkodierung umstellst, wird MySQL die beiden Latin1-Zeichen einzeln in UTF-8-Zeichen umschreiben.

Jetzt nochmal einzeln:

also die PMA-webanzeige ist auf utf-8 gestellt, die feldcodierung auf latin1, die daten in den feldern sind aber utf8 und werden auch inkl. aller umlaute richtig dargestellt.

Wenn das so ist, dann hast du beim Abfragen einen Fehler gemacht, der die falsche interne Kodierung kompensiert.

  • Feld-Kodierung = Latin1, Daten darin = UTF-8, Ü von MySQL als Ü interpretiert.
  • character_set_results steht auf Latin1, Client denkt aber UTF-8 und interpretiert statt Ü ein Ü. Scheinbar alles richtig.
  • Der PMA allerdings sollte darauf nicht reinfallen und "ordnungsgemäß" ein Ü anzeigen.

was passiert also, wenn ich die feldcodierung auf utf8 umstelle. wird dann der utf8-inhalt nochmal umcodiert. vermutlich, wenn er eh schon utf8 ist, nicht, oder?

In dem Fall hast du dann eine doppelte Kodierung. Denn wie der Feldinhalt von dir vorgesehen tatsächlich kodiert ist, weiß MySQL nicht. Es kann nur von dem ausgehen, was ihm konfiguriert wurde. "wenn er eh schon utf8 ist", muss das Feld also auch so konfiguriert sein, damit MySQL das so erkennen kann. Der PMA muss vorher alles richtig anzeigen, wenn du ein Feld von Kodierung X nach Y umstellen willst.

Lo!