Sonntag, 25. Mai 2014

MySQL Collations - nicht nur für Sortierreihenfolge!

Eine Collation (Kollation) ist in (My)SQL eine interne Sortierfolge, also eine Sortierreihenfolge (durch Textvergleich oder Binärwertvergleich) die für eine konkrete "alphabetische Sortierung" sorgt.

Doch das ist nur die halbe Wahrheit!
=> Da gibt es noch etwas ganz Wichtiges zu beachten, nämlich wie bzw. ob bestimmte Datensätze im Zusammenhang mit einem PRIMARY KEY oder UNIQUE KEY und der standardmäßigen Kollation 'latin1_swedish_ci' überhaupt gespeichert werden!

Angenommen eine Tabelle 'tbl' hat den Zeichensatz 'latin1' (Standard) und eben die Sortierfolge 'latin1_swedish_ci' (Standard; 'ci' = case-insensitive (Groß-/Kleinschreibung wird nicht beachtet)), als Primärschlüssel (eindeutig) wird ein Textfeld VARCHAR(10) verwendet.

Möchte man nun zuerst den Wert "DE" und danach "de" speichern, dann werden nicht beide Datensätze eingetragen, sondern nur einer davon! Die interne Sortierfolge hält beide Werte quasi für gleich.

Das kann natürlich auch sinnvoll sein (kumulierte Werte), kann aber eben genauso zu unerwarteten Ergebnissen führen (fehlende oder offenbar falsche Werte).

Abhilfe schafft hier z.B. die Collation 'latin1_general_ci' oder gleich 'latin1_general_cs' ('cs' = case sensitive), hier werden im obigen Beispiel beide Werte in eine Tabelle eingetragen bzw. gefunden. Eine weitere Collation wäre 'latin1_bin', diese behandelt Datenfelder nach ihren binären Werten (schneller), was aber eine unnatürliche Sortierreihenfolge zur Folge hat ('A', dann 'B' bis 'Z', und dann erst 'a', 'b', usw.). Damit deutsche Umlaute korrekt sortiert werden, wäre wiederum die Sortierfolge 'latin1_german2_ci' nötig (kein '_cs').

Beim zu bevorzugenden UTF-8-Zeichensatz (Unicode) gibt es keine (sprachabhängige) Erweiterung '_cs', nur '_ci' und '_bin'; bei diesem Multi-Byte-fähigen Zeichensatz werden im obigen Beispiel auch mit dem Suffix '_ci' beide Werte gespeichert!

Am allgemeinsten sind 'utf8_general_ci' (Standard für UTF-8; schneller) und 'utf8_unicode_ci' (etwas genauer (ß)) bzw. 'utf8mb4_unicode_ci' (erweiterter Zeichensatz); für deutsche Umlaute (Ä/ä) wäre aber wiederum 'utf8_german2_ci' sinnvoll.

Für einen Zeichensatz kann man die Sortierreihenfolge mit COLLATE aber auch in einem SELECT, also bei einer Abfrage (Query) individuell (sprachabhängig) bestimmen.

Links:


Keine Kommentare:

Kommentar veröffentlichen

Hinweis: Nur ein Mitglied dieses Blogs kann Kommentare posten.