paul: zeichensatz/umlaute-problem in mysql-datenbank

hallo zusammen,

ich habe eine mySql-datenbank und ein paar php-seiten, die einträge vornehmen/verändern.
irgendwo war der hund in den zeichensätzen drinnen, mir viel es erst auf, als ich die tabelle nach einem kleinen "ü" durchuchen wollte, und kein resultat bekam. mittlerweile weiss ich, dass mySQL dei suche case-insensitive durchführt, und dass der fehler in der abspeicherung der umlaute im falschen zeichensatz begründet ist. so weit so gut. nun habe ich diverse parameter geändert und den fehler soweit im griff. allerdings NUR, wenn ich meiner mySQL - query ein "SET NAMES utf8" vorausschicke. tue ich das nicht, werden die älteren, nicht korrigierten einträge richtig dargestellt, die neuen utf8-codierten einträge aber mit einem fragezeichen-platzhalter. das bedeutet doch, dass die abfrage selbst nicht in utf-8 übermittelt wird, oder? (wie gesagt, wenn ich SET NAMES utf8 vorausschicke, werden die neuen einträge richtig dargestellt...)

folgende parameter sind auf utf8 eingestellt:
1.das dokument selbst, in dem ich die db-abfrage anschaue
2. die tabelle selbst ist utf8_general_ci
3. die tabellenspalte selbst ist ebenfalls utf8_general_ci

nun kommt meine eigentliche frage:
wo sonst kann noch der hund begraben sein, dass die query SET NAMES utf8 notwendig ist. wenn alles korrekt auf utf8 voreingestellt ist, müsste sie ja überflüssig sein, oder?

hier noch die umgebungsparameter der gesamten mySQL-datenbank. ich kene mich d nicht wirklich aus, welche einstellung jetzt priorität hat od evtl. eine einstellung "überschreibt"??

auf der startseite von phpMyAdmin stehen für die db folgende parameter:
MySQL-Zeichensatz: UTF-8 Unicode (utf8)
Zeichensatz / Kollation der MySQL-Verbindung: utf8_unicode_ci ==> spießt sich das vielleicht mit dem für die tabelle eingestellten utf8_general_ci??

hier die parameter, die man in phpMyAdmin unter "Servervariablen und -einstellungen" angezeigt bekommt:

character set client utf8
(Globaler Wert) latin1
character set connection utf8
(Globaler Wert) latin1
character set database latin1
character set filesystem binary
character set results utf8
(Globaler Wert) latin1
character set server latin1
character set system utf8
character sets dir  C:\Program Files\MySQL\MySQL Server 5.0\share\charsets\ collation connection utf8_unicode_ci
(Globaler Wert) latin1_swedish_ci
collation database latin1_swedish_ci
collation server latin1_swedish_ci

hilfe:-(

paul

  1. schau mal weiter unten

    Kalle

  2. Hi!

    [...] wenn ich meiner mySQL - query ein "SET NAMES utf8" vorausschicke. tue ich das nicht, werden die älteren, nicht korrigierten einträge richtig dargestellt, die neuen utf8-codierten einträge aber mit einem fragezeichen-platzhalter. das bedeutet doch, dass die abfrage selbst nicht in utf-8 übermittelt wird, oder? (wie gesagt, wenn ich SET NAMES utf8 vorausschicke, werden die neuen einträge richtig dargestellt...)

    Es bedeutet genau das, was SET NAMES bewirkt. MySQL geht nach einem SET NAMES - oder besser mysql(i)_set_charset() - davon aus, dass die Daten auf der aktuellen Verbindung in der angegebenen Kodierung kommen und auch die Ergebnisse in dieser Kodierung geliefert werden sollen. Ohne SET NAMES geht MySQL davon aus, dass die System-Default-Kodierung für die Kommunikation mit dem Client verwendet werden soll.

    Das Problem mit deinen alten Datensätzen ist dies: Du hast zwar MySQL durch die Konfiguration der einzelnen Felder gesagt, dass es die Daten darin UTF-8-kodiert ablegen soll. Die Verbindung stand aber auf Latin1. MySQL hat daraufhin von Latin1 nach UTF-8 umkodiert. Allerdings hat es dabei in den von dir in UTF-8-kodiert gelieferten Daten die aus mehreren Byte bestehenden Sequenzen einiger Zeichen (Umlaute vorzugsweise) als jeweils ein Zeichen aufgefasst und auch nochmal nach UTF-8 umkodiert. Du siehst, wie MySQL die Daten beim Einfügen interpretiert hat, wenn du dir die alten Datensätze im PMA anschaust und zwei Zeichen pro Umlaut angezeigt werden. Wenn du nun das SET NAMES weglässt, kodiert MySQL beim Abfragen den Feldinhalt wieder zurück nach Latin1 und du interpretierst ihn als UTF-8 und hast kein Problem. Verwendest du jedoch "SET NAMES utf8" bleiben die Daten UTF-8-kodiert und du siehst die zwei Zeichen, die MySQL damals gelesen hat als zwei UTF-8-kodierte Zeichen und nicht als eins.

    gesendet - interpretiert - gespeichert | ausgeliefert - interpretiert - mit SET NAMES - interpretiert
    Du:    utf8-Ü                                                  utf8-Ü                          UTF8-ü
    MySQL:            latin1-ü       C3 83 C2 BC   latin1-ü                      UTF8-ü

    (Ich hoffe, dein Bildschirm/Browser-Viewport ist breit genug.)

    Es ist nur für deine Datenintegrität erforderlich, dass du die alten Daten korrigierst. Wenn es wenige sind, mach es mit dem PMA per Hand. Sind es viele, exportiere sie Latin1-kodiert und importiere sie so wie sie sind als UTF-8.

    folgende parameter sind auf utf8 eingestellt:
    1.das dokument selbst, in dem ich die db-abfrage anschaue
    2. die tabelle selbst ist utf8_general_ci
    3. die tabellenspalte selbst ist ebenfalls utf8_general_ci
    wo sonst kann noch der hund begraben sein, dass die query SET NAMES utf8 notwendig ist. wenn alles korrekt auf utf8 voreingestellt ist, müsste sie ja überflüssig sein, oder?

    Ja, "wenn". Aber das ist bei dir nicht der Fall, denn du hast die System-Default-Einstellung nicht beachtet.

    auf der startseite von phpMyAdmin stehen für die db folgende parameter:
    MySQL-Zeichensatz: UTF-8 Unicode (utf8)
    Zeichensatz / Kollation der MySQL-Verbindung: utf8_unicode_ci ==> spießt sich das vielleicht mit dem für die tabelle eingestellten utf8_general_ci??

    Das ist für dich uninteressant, weil das nur die Kommunikation zwischen dem PMA und MySQL betrifft, nicht aber die Verbindungen in deinen Scripten.

    hier die parameter, die man in phpMyAdmin unter "Servervariablen und -einstellungen" angezeigt bekommt:
    character set client utf8
    (Globaler Wert) latin1
    character set connection utf8
    (Globaler Wert) latin1
    character set database latin1
    character set filesystem binary
    character set results utf8
    (Globaler Wert) latin1
    character set server latin1
    character set system utf8
    character sets dir  C:\Program Files\MySQL\MySQL Server 5.0\share\charsets\ collation connection utf8_unicode_ci
    (Globaler Wert) latin1_swedish_ci
    collation database latin1_swedish_ci
    collation server latin1_swedish_ci

    Hiervon interessiert dich einzig jeweils der globale Wert, denn die anderen sind wiederum die induviduellen der PMA-Verbindung. Und siehe da, die von SET NAMES beeinflussten Werte stehen global alle auf latin1, weswegen du ein SET NAMES/mysql()_set_charset() benötigst.

    Lo!

    1. hi,
      erstmal danke, du hast meine zweifel bestätigt bzw. die nötigen infos geliefert!

      ich wusste z.b. nicht, auf was sich das "global" in der PMA-Oberfläche bezieht- es sind also genau das die relevanten einstellungen...

      Hiervon interessiert dich einzig jeweils der globale Wert, denn die anderen sind wiederum die induviduellen der PMA-Verbindung. Und siehe da, die von SET NAMES beeinflussten Werte stehen global alle auf latin1, weswegen du ein SET NAMES/mysql()_set_charset() benötigst.

      jetzt hätte ich noch zwei fragen:

      1. wen ich jetzt alle parameter auf utf-8 umstelle, wie wirkt sich das auf meine bestehenden daten aus? nur auf die umlaute/sonderzeichen, die ohnehin im moment so nicht brauchbar sind?
      2. kann ich diese globalen parameter dauerhaft verändern, wenn ich keinen direkten serverzugriff habe? (nur über php bzw. PMA)
      3. was ist der genaue unterschied zw. utf8_unicode_ci und utf8_general_ci bzw. was soll man (im deÜtschsprÄchigen rÄum) verwenden?

      danke nochmal

      p

      1. Hi!

        1. wen ich jetzt alle parameter auf utf-8 umstelle, wie wirkt sich das auf meine bestehenden daten aus? nur auf die umlaute/sonderzeichen, die ohnehin im moment so nicht brauchbar sind?

        Auf deine Daten wirkt sich nur das aus, was du direkt mit ihnen anstellst und das wäre die Kodierung der einzelnen Felder. Weder die Kodierungsangabe der Tabelle, noch der Datenbank noch die des Systems haben einen direkten Einfluss auf die bestehenden Daten, denn diese Nicht-Feld-Kodierungen sind nur Default-Werte für neu anzulegende Dinge.

        Die System-Einstellung (character-set-server) ist ausschließlich ein Default-Wert für neu angelegte Datenbanken, wenn dabei keine Kodierung genannt wurde.
        Der Wert für Datenbanken (character-set-database) ist hauptsächlich ein Default-Wert für neu angelegte Tabellen, wenn dabei keine Kodierung genannt wurde.
        Die Einstellung der Tabelle ist wiederum ein Default-Wert für neu angelegte Felder, wenn dabei keine Kodierung genannt wurde.
        Die Feldkodierung ist endlich eine, mit der wirklich was passiert: in der werden die Daten abgelegt. Kommen sie anderswoher anders kodiert (also wenn MySQL davon ausgeht, dass sie anders kodiert seien) werden sie umkodiert. Beim Auslesen wird auch gegebenenfalls umkodiert.
        Fir die Verbindung zum Client gibt es gleich drei Default-Werte (die alle von SET NAMES behandelt werden), die ich jetzt nicht erläutere. Wichtig ist nur, dass sie angeben, in welcher Kodierung ankommende Daten interpretiert werden und abgehende gesendet werden, sowie dass zum Einstellen SET NAMES und nicht SET CHARACTER SET zu verwenden ist, wenn mysql(i)_set_charset() nicht verwendet werden kann.

        1. kann ich diese globalen parameter dauerhaft verändern, wenn ich keinen direkten serverzugriff habe? (nur über php bzw. PMA)

        Nein. Zentral konfigurieren kann man sowieso nur character-set-server.

        1. was ist der genaue unterschied zw. utf8_unicode_ci und utf8_general_ci bzw. was soll man (im deÜtschsprÄchigen rÄum) verwenden?

        Bitte im Handbuch nachlesen und dann selbst entscheiden: Unicode Character Sets.

        Lo!

    2. hi nochmal,

      also ich glaube, ich habe jetzt konsistent utf8 eingestellt, es werden bei neuen einträgen auch die richtigen umlaute angezeigt und auch beim suchen case-insensitiv gefunden, also alles wunderbar;-)
      so weit so gut, nun aber zu den "altlast-daten":
      es sind ca. 600 datensätze mit jeweils zig feldern, in denen relativ oft werte mit umlauten oder ß etc. stehen. ein ex- und import, wie von dir vorgeschlagen, wäre also sinnvoll.

      ich habe folgendes probiert: in PMA als VSV-Daten exportieren und dann wieder in die datenbank-tabelle importieren (alles ersetzen ausgewählt) und bei zeichencodierung der datei "utf8" ausgewählt.

      ich bekomme zwar alles schön importiert, aber die umlaute sehen immer noch genauso chaotisch wie vorher aus. ein "Ä" ist vorher und nachher ein "Ä".
      die vorher bereits als Ä dargestellten Äs sind auch nachher Äs etc..

      hab ich irgendwas übersehen?

      Es ist nur für deine Datenintegrität erforderlich, dass du die alten Daten korrigierst. Wenn es wenige sind, mach es mit dem PMA per Hand. Sind es viele, exportiere sie Latin1-kodiert und importiere sie so wie sie sind als UTF-8.

      1. Hi!

        ich habe folgendes probiert: in PMA als VSV-Daten exportieren und dann wieder in die datenbank-tabelle importieren (alles ersetzen ausgewählt) und bei zeichencodierung der datei "utf8" ausgewählt.

        Du wolltest vermutlich CSV tippen. Du kannst auch ganz normal als SQL exportieren.

        Der PMA bietet nicht in jedem Fall die Möglichkeit, beim Exportieren eine Zeichenkodierung anzugeben. Ich meine, das ist eine Konfigurationseinstellung. Wenn du keine Auswahl für die Exportkodierung findest, dann bekommst du den die Daten UTF-8-kodiert. Du benötigst dann einen Editor, der umkodieren kann (oder ein anderes Tool mit dieser Funktionalität). Du musst da einmal als UTF-8 einlesen und ISO-8859-1 speichern. Das Ergebnis kannst du recht einfach in einem Browser prüfen. Datei öffnen -> Ansicht -> Zeichenkodierung -> auf UTF-8 stellen, dann solltest du die Umlaute richtig sehen. Wenn nicht, ist was verkehrt gelaufen, dann musst du mal ein konkretes Beispiel zeigen, was bei welcher Einstellung angezeigt wird (und was es deiner Meinung nach sein soll, wenn es nicht eindeutig aus dem Kontext zu erkennen ist).

        ich bekomme zwar alles schön importiert, aber die umlaute sehen immer noch genauso chaotisch wie vorher aus. ein "Ä" ist vorher und nachher ein "Ä".

        Beim Importieren kann man im PMA auf alle Fälle eine Kodierung angeben.

        Lo!

        1. hallo noch mal,

          »»Du benötigst dann einen Editor, der umkodieren kann (oder ein anderes Tool mit dieser Funktionalität). Du musst da einmal als UTF-8 einlesen und ISO-8859-1 speichern.

          ok, ich habs probiert (mit bbedit).
          folgendes problem trat auf: ich hab die daten als utf-8 eingelesen, aber beim speichern als latin1 bekomme ich die fehlermeldung "unmappable characters".

          konkret spießt es genau bei den (falsch dargestellten) umlauten. ein paar beispiele für die darstellung der umlaute. kannst du daraus auslesen, welchen weg die umlaute hinter sich haben?

          Ö ->  Ã–
          Ä ->  Ã„
          ß ->  ÃŸ
          Ü ->  Ãœ

          usw.

          was muss ich also tun, um diese kryptischen zeichen wieder richtig darzustellen???

          danke!

          paul

          1. Hi!

            ok, ich habs probiert (mit bbedit).
            folgendes problem trat auf: ich hab die daten als utf-8 eingelesen, aber beim speichern als latin1 bekomme ich die fehlermeldung "unmappable characters".

            Wo er Recht hat, hat er Recht.

            konkret spießt es genau bei den (falsch dargestellten) umlauten. ein paar beispiele für die darstellung der umlaute. kannst du daraus auslesen, welchen weg die umlaute hinter sich haben?
            Ö ->  Ã–
            Ä ->  Ã„
            ß ->  ÃŸ
            Ü ->  Ãœ

            Diese Zeichen verwenden Bytes aus dem Bereich 80..9F, der in ISO-8859-1 nicht belegt ist. Kann der Editor Windows-1252 speichern? Damit muss es gehen.

            Lo!

            1. Diese Zeichen verwenden Bytes aus dem Bereich 80..9F, der in ISO-8859-1 nicht belegt ist. Kann der Editor Windows-1252 speichern? Damit muss es gehen.

              vielen dank, so hats geklappt, ich sehe wieder alle umlaute und kann auch nach ihnen case-insensitive suchen, bin also endgültig im utf-8-zeitalter angekommen;-)

              woher weisst du das alles nur- ich meine, welche zeichencodierungen welche bytes verwenden etc...??

              p

              1. Hi!

                woher weisst du das alles nur- ich meine, welche zeichencodierungen welche bytes verwenden etc...??

                Das kann man alles nachlesen. Die Wikipedia ist wie so oft ein recht guter Startpunkt auch für dieses Thema.

                Einige Suchstichwörter lauten (hab grad keine Lust sie zu verlinken :-)

                UTF-8 und Unicode - dazu muss man auch den Unterschied zwischen Zeichenkodierung und Zeichensatz verstehen (und wissen, dass das ebenso gern falsch verwendet wird wie Homepage und Website im Deutschen)

                ISO-8859 - für die ISO-8859-Familie allgemein
                ISO-8859-1 - für die uns Westeuropäer interessierende Variante. Darin wird auch auf das weitgehend aber nicht ganz gleiche Windows-1252 verwiesen. Dass Latin1, so wie es MySQL versteht, in Wirklichkeit ein Windows-1252 ist, steht irgendwo im MySQL-Handbuch. Dass Browser auch Windows-1252 interpretieren, wenn sie solches aber als ISO-8859-1 deklariert bekommen, erfährt man auch im Laufe der Zeit.

                Lo!

                1. hi,

                  ISO-8859 - für die ISO-8859-Familie allgemein
                  ISO-8859-1 - für die uns Westeuropäer interessierende Variante. Darin wird auch auf das weitgehend aber nicht ganz gleiche Windows-1252 verwiesen. Dass Latin1, so wie es MySQL versteht, in Wirklichkeit ein Windows-1252 ist, steht irgendwo im MySQL-Handbuch. Dass Browser auch Windows-1252 interpretieren, wenn sie solches aber als ISO-8859-1 deklariert bekommen, erfährt man auch im Laufe der Zeit.

                  puh, ist das aber kompliziert- das kann man ja eigentlich fast nur verstehen bzw. sich auch tatsächlich merken, wenn man am eigenen leib probleme damit bekommen hat, oder? d.h. man muss halt seine erfahrungen machen. jetzt frag ich mich allerdings, wenn utf8 ja beinahe alle zeichen abdeckt, ist es dann nicht ohnehin dringend anzuraten, immer damit zu arbeiten, und auch evtl vorhandene daten einmal zu konvertieren, um dann endgültig ruhe zu haben? man kan ja z.b. auch in westeuropa nicht ausschließen, dass jemand z.b. irgendwelche kryptischen zeichen in seinem namen hat... macht es irgendeinen sinn, sich auf einen bestimmten, kleineren zeichensatz zu beschränken?

                  p

                  1. Hallo

                    jetzt frag ich mich allerdings, wenn utf8 ja beinahe alle zeichen abdeckt, ist es dann nicht ohnehin dringend anzuraten, immer damit zu arbeiten, und auch evtl vorhandene daten einmal zu konvertieren, um dann endgültig ruhe zu haben?

                    ja

                    man kan ja z.b. auch in westeuropa nicht ausschließen, dass jemand z.b. irgendwelche kryptischen zeichen in seinem namen hat... macht es irgendeinen sinn, sich auf einen bestimmten, kleineren zeichensatz zu beschränken?

                    nein

                    Tschö, Auge

                    --
                    Verschiedene Glocken läuteten in der Stadt, und jede von ihnen vertrat eine ganz persönliche Meinung darüber, wann es Mitternacht war.
                    Terry Pratchett, "Wachen! Wachen!"
                    Veranstaltungsdatenbank Vdb 0.3
                2. ach ja, eine letzte frage noch:

                  ich habe jetzt verstanden, dass die einzig für meine daten relevante einstellung, soferne die codierung seitens meiner db-verbingung passt,die feldcodierung in PMA ist. ich habe nun dank deiner anleitung alle daten utf-codiert vorliegen, aber die felcodierung steht teilweise auf latin. was passiert nun, wenn ich die codierung auf utf-8 umstelle? für zukünftige daten ist das wohl sinnvoll/notwendig? aber was ist mit den bestehenden? ich nehme an, bei denen ändert sich dadurch nichts, oder? kann ich da getrost umstellen?

                  danke nochmals, du bist eine riesen hilfe gewesen - wikipedia/google hilft auch sehr, aber bei so heiklen eingriffen in bestehende datten war mir das alleinige prinzip "learnig by googling" ein wenig zu riskant;-)

                  p

                  1. Hi!

                    ach ja, eine letzte frage noch:

                    Sei nicht so voreilig, vielleicht hast du ja noch eine Frage zu dem was ich dir antworte :-)

                    ich habe jetzt verstanden, dass die einzig für meine daten relevante einstellung, soferne die codierung seitens meiner db-verbingung passt,die feldcodierung in PMA ist.

                    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.

                    ich habe nun dank deiner anleitung alle daten utf-codiert vorliegen, aber die felcodierung steht teilweise auf latin. was passiert nun, wenn ich die codierung auf utf-8 umstelle?

                    MySQL ist so nett und kodiert das um, wenn du das mit einem passenden ALTER-Statement machst oder dem PMA, der ein solches für dich erzeugt und ausführt. Voraussetzung, dass das problemlos klappt, ist natürlich, dass die Daten im Feld auch in der eingestellten Kodierung stehen und nicht durch frühere Fehler in einer falschen Kodierung gesendet wurden. Wenn der PMA alles richtig anzeigt, ist üblicherweise alles in Ordnung.

                    danke nochmals, du bist eine riesen hilfe gewesen - wikipedia/google hilft auch sehr, aber bei so heiklen eingriffen in bestehende datten war mir das alleinige prinzip "learnig by googling" ein wenig zu riskant;-)

                    Solange du die (ob per Google oder durch Fragen) gewonnenen Informationen an einer Kopie deiner Daten verifizierst ist alles in Ordnung. Auch ich mache Fehler - hast du ja in diesem Thread gesehen. Beim Kopieren von Tabellen oder Datenbanken (im PMA unter Operationen/Operations zu finden) tritt normalerweise keine Datenveränderung ein. Das Original solltest du erst nach dem erfolgreichen Versuch an der Kopie ändern. Es kann auch günstig sein, das Original umbenannt noch eine Weile aufzuheben, falls noch irgendwelche Fehler übersehen wurden und sich erst später offenbaren.

                    Lo!

                    1. hallo, (ein allerallervorletztes mal;-)

                      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??

                      ich habe nun dank deiner anleitung alle daten utf-codiert vorliegen, aber die felcodierung steht teilweise auf latin. was passiert nun, wenn ich die codierung auf utf-8 umstelle?

                      MySQL ist so nett und kodiert das um, wenn du das mit einem passenden ALTER-Statement machst oder dem PMA, der ein solches für dich erzeugt und ausführt. Voraussetzung, dass das problemlos klappt, ist natürlich, dass die Daten im Feld auch in der eingestellten Kodierung stehen und nicht durch frühere Fehler in einer falschen Kodierung gesendet wurden. Wenn der PMA alles richtig anzeigt, ist üblicherweise alles in Ordnung.

                      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?

                      Beim Kopieren von Tabellen oder Datenbanken (im PMA unter Operationen/Operations zu finden) tritt normalerweise keine Datenveränderung ein. Das Original solltest du erst nach dem erfolgreichen Versuch an der Kopie ändern. Es kann auch günstig sein, das Original umbenannt noch eine Weile aufzuheben, falls noch irgendwelche Fehler übersehen wurden und sich erst später offenbaren.

                      ja, das hab ich eh gemacht. ich wollte nur trotzdem von einer "lebenden peson" nochmals alles erklärt haben, erstens verstehe ich manches so schneller, und ausserdem hält doppelt natürlich besser. horrorszenario wäre ja z.b.: ich glaube, alles verstanden zu haben, verifiziere anhand einer kopie, alles sieht richtig aus, ich gebe die db zur weiteren verwendung frei, die db wird kräftig akualisiert, und nach zwei monaten stellt sich ein grober fehler heraus- dann kan ich mir die alte sicherungskopie aber in die haare schmieren, weil man viele felder manuell ergänzen/auf richtigkeit überprüfen müsste. daher lieber jetzt möglichst alles ausschöpfen, um sicherzugehen. einverstanden?

                      allerverbindlichstendank!

                      p

                      1. 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!