50226 - Witi's Blog

Suche
Archive
Kategorien

MySQL: Umlaute und UTF-8

Wer in seiner Applikation auf UTF-8 als Zeichensatz setzt, wird in den entsprechenden Spalten einer MySQL-Tabelle in der Regel auch auf Kollationen wie utf8_unicode_ci oder das ältere utf8_general_ci setzen. Dass dies allerdings zu Problemen mit Umlauten führen kann, zeige ich euch im folgenden Beitrag.



Konfiguration


Als Ausgangsgrundlage sei angenommen, dass ihr euren MySQL-Server korrekt konfiguriert habt. Hierfür könnt ihr die Anleitung von Gerd Riesselmann zu Rate ziehen.


Beispiel


Für unser Beispiel greifen wir auf die Tabelle aus der verlinkten Anleitung, passen sie jedoch an einer kleinen Stelle an: Wir möchten, dass die Tabelle nur einzigartige Werte enthält:


create table sorttest (value varchar(15) unique) default character set 'UTF8';

Mit folgendem Befehl könnt ihr überprüfen, dass für die Spalte value die Kollation utf8_unicode_ci benutzt wird.


mysql> SHOW FULL COLUMNS FROM sorttest;
+-------+-------------+-----------------+------+-----+---------+-------+---------------------------------+---------+
| Field | Type        | Collation       | Null | Key | Default | Extra | Privileges                      | Comment |
+-------+-------------+-----------------+------+-----+---------+-------+---------------------------------+---------+
| value | varchar(15) | utf8_unicode_ci | YES  | UNI | NULL    |       | select,insert,update,references |         |
+-------+-------------+-----------------+------+-----+---------+-------+---------------------------------+---------+
1 row in set (0.00 sec)

Nun versuchen wir die Zeichenketten 'aaa' und 'äää' einzufügen.


mysql> INSERT INTO sorttest values('aaa');
Query OK, 1 row affected (0.03 sec)

mysql> INSERT INTO sorttest values('äää');
ERROR 1062 (23000): Duplicate entry 'äää' for key 'value'

Oha, das funktioniert also nicht. 'aaa' und 'äää' sollen identisch sein.


Erklärung


In der offiziellen Dokumentation von MySQL findet sich in der Beschreibung der Unicode-Zeichensätze folgendes Zitat:


Die folgenden Gleichstellungen beispielsweise sind sowohl in
utf8_general_ci als auch in
utf8_unicode_ci zutreffend:


Ä = A
Ö = O
Ü = U

Wenn man sich mal umschaut wird man feststellen, dass recht viele Projekte diese Kollationen verwenden, wo es auch zu konkreten Problemen führt. Ein konkretes Beispiel ist eine Benutzertabelle in denen Benutzernamen gespeichert werden. Existiert bspw ein Benutzer "foobär", wird es beim Versuch den Benutzer "foobar" zu speichern, zu einem Fehler kommen. foobar ist nun mal identisch mit foobär. Zumindest in utf8_general_ci als auch in utf8_unicode_ci.


utf8_bin


Die Lösung für unser Problem lautet die Kollation utf8_bin. Hier werden die einzelnen Buchstaben auf Binärebene überprüft. Hier muss allerdings beachtet werden, dass bei utf8_bin Groß- und Kleinbeschreibung eine Rolle spielt, im Gegensatz zu utf8_general_ci und in utf8_unicode_ci (Case insensitive).


Passen wir nun unser Beispiel von oben an, können wir beide Einträge speichern:


mysql> create table sorttest2 (value varchar(15) unique) default character set 'UTF8' collate utf8_bin;

mysql> show full columns from sorttest2;
+-------+-------------+-----------+------+-----+---------+-------+---------------------------------+---------+
| Field | Type        | Collation | Null | Key | Default | Extra | Privileges                      | Comment |
+-------+-------------+-----------+------+-----+---------+-------+---------------------------------+---------+
| value | varchar(15) | utf8_bin  | YES  | UNI | NULL    |       | select,insert,update,references |         |
+-------+-------------+-----------+------+-----+---------+-------+---------------------------------+---------+
1 row in set (0.00 sec)

mysql> insert into sorttest2 values('aaa');
Query OK, 1 row affected (0.00 sec)

mysql> insert into sorttest2 values('äää');
Query OK, 1 row affected (0.00 sec)

mysql> select value from sorttest2;
+--------+
| value  |
+--------+
| aaa    |
| äää    |
+--------+
2 rows in set (0.00 sec)
in MySQL - Freitag, 2. Dezember 2011 um 09:35 | Noch keine Kommentare
Trackbacks
Keine Trackbacks
Kommentare
Noch keine Kommentare
Kommentar schreiben
Umschließende Sterne heben ein Wort hervor (*wort*), per _wort_ kann ein Wort unterstrichen werden.
Standard-Text Smilies wie :-) und ;-) werden zu Bildern konvertiert.
Die angegebene E-Mail-Adresse wird nicht dargestellt, sondern nur für eventuelle Benachrichtigungen verwendet.

Um maschinelle und automatische Übertragung von Spamkommentaren zu verhindern, bitte die Zeichenfolge im dargestellten Bild in der Eingabemaske eintragen. Nur wenn die Zeichenfolge richtig eingegeben wurde, kann der Kommentar angenommen werden. Bitte beachten Sie, dass Ihr Browser Cookies unterstützen muss, um dieses Verfahren anzuwenden.
CAPTCHA