MySQL - Charset/Kollation

MarcoPaulini

Grünschnabel
Hallo allerseits,

ich stehe vor einem etwas größeren Web-Projekt und designe gerade die MySQL Datenbank. Jetzt stehe ich eigentlich vor der Wahl, welches Charset und welche Kollation ich nehmen soll. Da es international wird, war mein erster Gedanke "utf8!". Die passende Kollation dazu zu finden stellt sich jedoch als die Suche nach der Nadel im Heuhaufen raus...

Meine Anforderungen sind:

- 'Muller' != 'Müller'
- Where Name = 'Muller' soll nur "Muller" zurückgeben, nicht 'Müller'
- Möglichst Case-Insensitive, also Where Attribut = 'muller' soll auch "Muller" zurückgeben
- UNIQU-Index auf z.B. Attribut "Name" soll ebenfalls 'Muller' != 'Müller' behandeln, sie sollen also koexistieren.

Derzeit beste Lösung:

Charset utf8 mit Kollation utf8_bin. Das einzige große Manko, es ist Case Sensitive, da wirklich die Binärdaten abgeglichen werden, ohne länderspezifische Gegebenheiten. Bei einer Suche hab ich 2 Möglichkeiten gefunden, das ganze Case-Insensitive zu machen:

LOWER(`Attribut`) LIKE LOWER(keyword)
oder
CONVERT(`Attribut` USING latin1) COLLATE latin1_german2_ci LIKE CONVERT(keyword USING latin1) COLLATE latin1_german2_ci

Wenn man sich jedoch überlegt was bei beiden passiert, merkt man, dass das auch nicht das Gelbe vom Ei ist. An sich funktioniert das, aber ein vorhandener Index auf `Attribut` wird damit eigentlich komplett ausgehebelt! Beim Oberen wird jeder Wert LOWER() konvertiert und beim Unteren jeder Wert in ein anderes Charset mit einer anderen Kollation konvertiert. Performant ist also bei einer größeren Datenmenge etwas anderes...

Also im Prinzip suche ich etwas wie "utf8_german2_ci" oder "utf8_bin_ci" .

Gruß,
Marco
 
http://use-the-index-luke.com/de/sql/where/funktionen/gross-klein-schreibung-ignorieren

Aber soviel ich weiss, kennt MySQL keine Funktions-basierenden Indizes... (ein weiterer Grund warum ich PostgreSQL gegenüber MySQL vorziehen würde).

Daher sehe ich als einzigen Workaround dass du eine weitere Spalte für das Attribut einführst, wo alles UPPER oder LOWER case ist und den Index auf diese neue Spalte legst. Als Collation kannst du dann utf8_bin brauchen.
Leider unterstützt MySQL auch keine Virtuelle Spalten, somit musst du beim INSERT/UPDATE selber dafür sorgen, dass die neue Spalte korrekt befüllt wird, oder aber du brauchst einen Trigger dafür.

http://use-the-index-luke.com/de/sql/where/funktionen
 
Zuletzt bearbeitet:

Neue Beiträge

Zurück