Zeichensätze
Zeichensätze sind eine ewige Quelle der Erbauung: Nichts ist so, wie es scheint.
Bevor Sie an die praktische Umsetzung gehen: Der Untertitel ist kein Spaß. Nahezu jedes Programm versucht, den Zeichensatz des jeweiligen Datensatzes (ganz gleich ob einfacher Text, Tabelle oder Datenbankinhalt) automatisch zu erkennen und korrekt darzustellen. Sie werden also nur in den seltensten Fällen sehen, was tatsächlich da ist. In der Regel sehen sie die Interpretation der Textverarbeitung, des Datenbankclients, des Editors oder des Browsers.
Weil meine Kunden Shops in einer ganzen Reihe von Fremdsprachen vorhalten, muß ich mich mit den Hintergründen auseinandersetzen. Und weil ich mich nicht mit den Eigenheiten jeder Sprache auseinandersetzen will, beschäftige ich mich mit dem internationalen Zeichensatz utf-8.
Man könnte meinen, mit einer Umkodierung wäre das Thema erledigt, aber weit gefehlt. Es geht bei dem Thema nicht nur um die richtige Darstellung eines Zeichens, sondern auch um Sortierreihenfolge und richtig funktionierende Suchfunktionen. Für die Sortierfolge gibt es im Handbuch ein gutes Beispiel. Für die Suchfunktion kenne ich den Fall für die Suche nach einem Wort mit Umlaut, wobei ich die Groß/Kleinschreibung ignorieren will.
Betrachten wir das am Beispiel eines Umlauts in der Zeichensatztabelle für Westeuropa (iso-8859-1, oder auch latin1):
214 Ö LATIN CAPITAL LETTER O WITH DIAERESIS
366 ö LATIN SMALL LETTER O WITH DIAERESIS
In diesem Fall soll die Datenbank also die Dezimalzahlen 214 und 366 gleich behandeln. Diese Beispiele werden wir später für Tests auf korrekte Funktionalität brauchen.
In der Praxis bietet MySQL in der vorliegenden Version 22 verschieden Collations für den Zeichensatz utf8 an. Dazu ein wenig SQL:
select collation_name from information_schema.collations where collation_name like 'utf8%' order by collation_name;
show variables like 'character_set%';
show variables like 'collation%';
Die gezeigten Variablen sind von der jeweiligen Konfiguration abhängig, defaults können pro Datenbank, Verbindung und Client abweichen. Um auf die sichere Seite zu kommen, halte ich es für notwendig, die wesentlichen Parameter beim Anlegen der Datenbank und beim Verbindungsaufbau vorzugeben.
create database xtm106_8 default character set utf8 default collate utf8_unicode_ci;
Auf utf8_unicode_ci kam ich durch das Handbuch und die Rechtschreibreform, die gerade bei der Verwendung von "ss" und "ß" etliche Änderungen mit sich brachte:
"utf8_general_ci
also is satisfactory for both German and French, except that “ß
” is equal to “s
”, and not to “ss
”. If this is acceptable for your application, you should use utf8_general_ci
because it is faster. Otherwise, use utf8_unicode_ci
because it is more accurate."
Trotz dieser Vorgaben zeigt mir die Abfrage der Variablen noch nicht das gewünschte Ergebnis:
mysql> show variables like 'character_set%';
+--------------------------+----------------------------+
| Variable_name | Value |
+--------------------------+----------------------------+
| character_set_client | latin1 |
| character_set_connection | latin1 |
| character_set_database | utf8 |
| character_set_filesystem | binary |
| character_set_results | latin1 |
| character_set_server | latin1 |
| character_set_system | utf8 |
| character_sets_dir | /usr/share/mysql/charsets/ |
+--------------------------+----------------------------+
8 rows in set (0.00 sec)
mysql> show variables like 'collation%';
+----------------------+-------------------+
| Variable_name | Value |
+----------------------+-------------------+
| collation_connection | latin1_swedish_ci |
| collation_database | utf8_unicode_ci |
| collation_server | latin1_swedish_ci |
+----------------------+-------------------+
3 rows in set (0.00 sec)
Es ist also erforderlich, auch die Clientverbindung zu initialisieren:
set names utf8 collate utf8_unicode_ci;
mysql> show variables like 'collation%';
+----------------------+-------------------+
| Variable_name | Value |
+----------------------+-------------------+
| collation_connection | utf8_unicode_ci |
| collation_database | utf8_unicode_ci |
| collation_server | latin1_swedish_ci |
+----------------------+-------------------+
3 rows in set (0.00 sec)
mysql> show variables like 'character_set%';
+--------------------------+----------------------------+
| Variable_name | Value |
+--------------------------+----------------------------+
| character_set_client | utf8 |
| character_set_connection | utf8 |
| character_set_database | utf8 |
| character_set_filesystem | binary |
| character_set_results | utf8 |
| character_set_server | latin1 |
| character_set_system | utf8 |
| character_sets_dir | /usr/share/mysql/charsets/ |
+--------------------------+----------------------------+
8 rows in set (0.00 sec)
Damit sollte ich nun eine hinreichende Grundlage für vernünftiges Arbeiten haben.