split.s: nach UTF8 konvertieren (mysql)

Hi!

Meine Frage betrifft mySQL ab Version 4.1.x und lautet:

Ich möchte gerne latin1 Spalten nach utf-8 konvertieren. Dazu habe ich folgendes Kommando gefunden:

  
ALTER TABLE orte MODIFY stadt VARCHAR(255) NOT NULL CHARACTER SET utf8  

Das funktioniert auch, denn neue Einträge werden nach einem INSERT als UTF8 angelegt.
Aber leider betrifft das nicht diejenigen, die schon vorher in der Tabelle vorhanden waren!
Kennt jemand vielleicht die Vollendung dieses Vorgehens?

  1. Kennt jemand vielleicht die Vollendung dieses Vorgehens?

    dump erstellen, dump konvertieren, datenbank umstellen, dump importieren - die sicherste methode ist mit ein paar zeilen commandline erledigt

    1. frag doch erstmal ob ich z.B. BLOB's oder sowas in der Datenbank habe.
      Übrigens, die Datenbank ist einige GB groß und enthält BLOB's

      1. frag doch erstmal ob ich z.B. BLOB's oder sowas in der Datenbank habe.

        was gehen blobs zeichencodierungen an?
        zudem, warum sollte man diese nicht auch dumpen können?

        http://dev.mysql.com/doc/refman/5.0/en/mysqldump.html#option_mysqldump_hex-blob

        Übrigens, die Datenbank ist einige GB groß und enthält BLOB's

        welches betriebsystem und welchen editor verwendest du, windows mit fat32 und  notepad?

        1. Natürlich kann man blobs dumpen. Aber warum man Dumps mit Blobs nicht einfach mit einem Editor oder normalen Zeichenkonverter bearbeiten kann sollte dir doch bewusst sein ;)

          1. Natürlich kann man blobs dumpen. Aber warum man Dumps mit Blobs nicht einfach mit einem Editor oder normalen Zeichenkonverter bearbeiten kann sollte dir doch bewusst sein ;)

            natürlich - aber warum solltest du in ein blob fliesstext mit zeichencodierung packen?

            blobs sind für größere binärdatenmengen gedacht - grafiken, audiodatein, filme, ausführbare datein

            wenn du eine große textdatei in binärform in ein blob überträgst, hast du etwas falsch gemacht oder einen wirklich verdammt guten grund dafür

            1. echo $begrüßung;

              blobs sind für größere binärdatenmengen gedacht - grafiken, audiodatein, filme, ausführbare datein
              wenn du eine große textdatei in binärform in ein blob überträgst, hast du etwas falsch gemacht oder einen wirklich verdammt guten grund dafür

              Darum geht es nicht. Es können zufällig Bytewerte und Bytesequenzen im BLOB enthalten sein, die nicht geändert werden dürfen. Dein Vorschlag war "dump erstellen, dump konvertieren". Das geht aber nur, wenn alle Bytes/Bytefolgen im Dump auf einheitliche Weise umkodiert werden können. Der Texteditor ist nicht so intelligent, nur die Textdaten des Dumps zu berücksichtigen, und die BLOB-Felder außen vor zu lassen. Besser ist es, zu analysieren, was konkret für Fehler in der Datenhaltung zu sehen sind, und dann gezielt diese fehlerhaften Felder mit Hilfe MySQL-eigener Mitteln behandeln.

              echo "$verabschiedung $name";

              1. Darum geht es nicht. Es können zufällig Bytewerte und Bytesequenzen im BLOB enthalten sein, die nicht geändert werden dürfen.

                sicher geht es darum - siehe hier, --hex-blob ist die "lösung"
                http://forum.de.selfhtml.org/?t=171410&m=1122034

                wenn man die zeichenkodierung von zb ansi nach utf-8 ändert, werden die hexadezimal notierten zeichen nicht verändert (das ist absichtlich so und nicht ein glücklicher zufall) - x, 0-9 und a-f liegen alle im ascii-bereich von der seite kann eigentlich recht gefahrlos auf mit dieser methode konvertieren

                1. echo $begrüßung;

                  Darum geht es nicht. Es können zufällig Bytewerte und Bytesequenzen im BLOB enthalten sein, die nicht geändert werden dürfen.
                  sicher geht es darum - siehe hier, --hex-blob ist die "lösung"
                  http://forum.de.selfhtml.org/?t=171410&m=1122034

                  Gut, damit sollte es gehen. (Wie dir aber aufgefallen sein sollte, haben sowohl split.s als auch ich diesen wichtigen Hinweis mit der Hex-Dump-Option übersehen, weil er sich in einem Link versteckte und nicht explizit als Argument angeführt wurde.)

                  wenn man die zeichenkodierung von zb ansi nach utf-8 ändert, werden die hexadezimal notierten zeichen nicht verändert (das ist absichtlich so und nicht ein glücklicher zufall) - x, 0-9 und a-f liegen alle im ascii-bereich von der seite kann eigentlich recht gefahrlos auf mit dieser methode konvertieren

                  Das ist nun klar. Ob aber die Umkodierung so herum oder in anderen Richtungen erfolgen muss, ist immer noch nicht geklärt.

                  Vorschlag zur weiteren Vorgehensweise: Dump mit --hex-dump als Option erstellen. Mit der Option --default-character-set=... kann man etwas experimentieren. Als erstes tät ich utf8 probieren. Sind die Umlaute dann richtig UTF-8-kodiert, scheint soweit alles in Ordnung zu sein. Doch dann hätte auch ein einfaches Umstellen der Feld-Kodierung ein brauchbares Ergebnis bringen müssen. Ich vermute, dass es damit wohl eher eine doppelte UTF-8-Kodierung entstehen wird. In dem Fall sollte der Dump mit latin1 ausgegeben werden. Wenn dabei eine normale UTF-8-Kodierung entsteht, ist kein weiteres Umwandeln nötig. Es kann dann die Tabelle geleert und die Feldkodierung(en) (Feldkodierungen! Tabellenkodierung (oder Datenbankkodierung) allein reicht nicht. Das sind nur Defaultwerte für neu anzulegende Felder (und Tabellen)) umgestellt werden. Den Dump kann man nun unter Angabe von --default-character-set=utf8 mit dem Kommandozeilentool mysql einlesen. (Von einem Import über phpMyAdmin ist bei der erwähnten Tabellengröße abzusehen.)

                  Wenn der Fall ein ganz anderer als eben erwähnt ist, bitte genau beschreiben, wie sich die Umlaute darstellen und wie diese Darstellung erzeugt wurde (welcher Editor mit welchen Einstellungen wurde verwendet). Besser, da eindeutig, ist es, sich direkt die Byte-Werte anzusehen. Ein Editor mit Hex-Dump-/-Edit-Fähigkeit oder ein Hexdump des Dumps wäre hier von Vorteil.

                  Bitte bei all dem Experimentieren nicht vergessen, eine Sicherungskopie des derzeitigen Stands anzufertigen!

                  echo "$verabschiedung $name";

            2. Moin!

              wenn du eine große textdatei in binärform in ein blob überträgst, hast du etwas falsch gemacht oder einen wirklich verdammt guten grund dafür

              Case-sensitive Textsuche z.B.

              - Sven Rautenberg

              --
              "Love your nation - respect the others."
              1. echo $begrüßung;

                wenn du eine große textdatei in binärform in ein blob überträgst, hast du etwas falsch gemacht oder einen wirklich verdammt guten grund dafür
                Case-sensitive Textsuche z.B.

                Dafür eignet sich TEXT mit der Kollation *_bin besser. Ein BLOB vergleicht ja nicht nach Zeichen sondern nach Bytes. Eine Kodierungs-/Kollationsangabe ist da nicht möglich. Mit TEXT in der Kollation utf8_bin beispielsweise werden Zeichen mit mehreren Bytes wenigstens als solche behandelt und nicht jedes Byte einzeln.

                echo "$verabschiedung $name";

                1. Dafür eignet sich TEXT mit der Kollation *_bin besser. Ein BLOB vergleicht ja nicht nach Zeichen sondern nach Bytes. Eine Kodierungs-/Kollationsangabe ist da nicht möglich. Mit TEXT in der Kollation utf8_bin beispielsweise werden Zeichen mit mehreren Bytes wenigstens als solche behandelt und nicht jedes Byte einzeln.

                  _bin ist auch nicht unbedingt optimal - ich würde eine der vielen cs-kollationen verwenden ;)

                  wenn ich nach A suche möchte ich als österreicher z.B. Äpfel und Ätherschmaus auch finden ;)

                  1. echo $begrüßung;

                    _bin ist auch nicht unbedingt optimal - ich würde eine der vielen cs-kollationen verwenden ;)
                    wenn ich nach A suche möchte ich als österreicher z.B. Äpfel und Ätherschmaus auch finden ;)

                    Welche der "vielen cs-kollationen" würdest du für diesen Fall nehmen? Als Vorgabe sei außerdem Unicode-Fähigkeit verlangt.

                    echo "$verabschiedung $name";

                    1. Welche der "vielen cs-kollationen" würdest du für diesen Fall nehmen? Als Vorgabe sei außerdem Unicode-Fähigkeit verlangt.

                      latin1_german_cs ist für deutsche inhalte natürlich am interessantesten, zukunftsorientiert ist man aber in allen fällen mit utf-8_general_ci (die utf-8 bzw unicode-vorgabe hatte ich jetzt ganz vergessen ;)) unterwegs - wenn mans nun wirklich case-senstive haben will, bleibt nicht mehr viel übrig utf-8_general_cs ist zwar implementiert, ist afaik aber aufgrund eines bugs ?! nicht in den standard-binarys von mysql enthalten

                      mit uft-8_bin hat man halt den nachteil, dass exakt verglichen wird und man eben mit einer suche nach A kein Ä findet oder ähnliches sondern eben nur exakt das selbe zeichen

                      1. echo $begrüßung;

                        Welche der "vielen cs-kollationen" würdest du für diesen Fall nehmen? Als Vorgabe sei außerdem Unicode-Fähigkeit verlangt.
                        latin1_german_cs ist für deutsche inhalte natürlich am interessantesten,

                        Diese Kollation gibt es unter MySQL 5.0.51 nicht. Es gibt für latin1 mit _cs nur latin1_general_cs. Und damit ist A ungleich Ä.

                        echo "$verabschiedung $name";

  2. echo $begrüßung;

    Ich möchte gerne latin1 Spalten nach utf-8 konvertieren. Dazu habe ich folgendes Kommando gefunden:
    ALTER TABLE orte MODIFY stadt VARCHAR(255) NOT NULL CHARACTER SET utf8
    Das funktioniert auch, denn neue Einträge werden nach einem INSERT als UTF8 angelegt.

    Da die Datenhaltung eine Blackbox ist, wie hast du das überprüft?

    Aber leider betrifft das nicht diejenigen, die schon vorher in der Tabelle vorhanden waren!

    Dann hattest du vorher einen Fehler und die Daten passten nicht zur angegebenen Kodierung. Das Ändern der Feldkodierung hat einen Umkodiervorgang zur Folge. Der kann natürlich nur dann fehlerfrei durchgeführt werden, wenn Kodierung und Kodierungsangabe übereingestimmt haben.

    Kennt jemand vielleicht die Vollendung dieses Vorgehens?

    Such zunächst den Fehler. Vielleicht liegt es am nicht beachteten Einstellen der Verbindungskodierung. Wenn du genau herausgefunden hast, was bisher schief gelaufen ist, bzw. wie die Umlaute sich nun darstellen, kann man Gegenmaßnahmen versuchen. Auf alle Fälle solltest du dir vor weiteren Versuchen eine Sicherungskopie der Tabelle(n) anlegen. Nicht dass noch mehr kaputt geht als es bisher (vermutlich) schon ist. Dann hilft nur noch Handarbeit.

    echo "$verabschiedung $name";