latin1_german2_ci, utf-8

latin1_german2_ci, utf-8

am 19.05.2006 18:54:39 von steffen horst

Hallo,

ich hab eine Datenbank mit in UTF-8 gespeicherten Daten. Die Dateien auf
dem Webserver sind in UTF-8 und dementsprechend die SQL-Anfragen ebenso.

Nun brauche ich zwecks Gleichbehandlung von ss/ß und ü/ue bei einer Suche
die Kollation latin1_german2_ci. Was ist dafür die beste Lösung? Muss ich
nun alles auf Latin1 umstellen?

Es geht um MySQL 5.0.

Schöne Grüße, Steffen

Re: latin1_german2_ci, utf-8

am 19.05.2006 20:16:43 von Axel Schwenke

"steffen horst" wrote:
>
> ich hab eine Datenbank mit in UTF-8 gespeicherten Daten. Die Dateien auf
> dem Webserver sind in UTF-8 und dementsprechend die SQL-Anfragen ebenso.
>
> Nun brauche ich zwecks Gleichbehandlung von ss/ß und ü/ue bei einer Suche
> die Kollation latin1_german2_ci. Was ist dafür die beste Lösung? Muss ich
> nun alles auf Latin1 umstellen?

Unangenehmerweise gibt es (noch) keine deutsche Collation für UTF8.
Aber solange du nur latin1-Zeichen in den entsprechenden Spalten
speichern willst, spricht nichts dagegen, diese auf die Collation
latin1_german2_ci umzustellen. Die Applikation kann ja auch weiter
UTF8 verwenden. Wenn du das Connection-Encoding auf UTF8 stellst,
konvertiert MySQL die Ergebnisse automatisch.



Alternativ kannst du bei jeder Vergleichsoperation in latin1 wandeln
und die Collation vorgeben:

SELECT ...
WHERE CONVERT(utf8_spalte USING latin1)
= 'suchstring' COLLATE latin1_german2_ci


XL

Re: latin1_german2_ci, utf-8

am 20.05.2006 17:09:18 von steffen horst

Hallo,

> Unangenehmerweise gibt es (noch) keine deutsche Collation für UTF8.
> Aber solange du nur latin1-Zeichen in den entsprechenden Spalten
> speichern willst, spricht nichts dagegen, diese auf die Collation
> latin1_german2_ci umzustellen. Die Applikation kann ja auch weiter
> UTF8 verwenden. Wenn du das Connection-Encoding auf UTF8 stellst,
> konvertiert MySQL die Ergebnisse automatisch.

Vielen Dank schonmal für die Lösungen! Ich hab jetzt mal die Datenbank,
alle Tabellen und Spalten auf latin1_german2_ci umgestellt.
Beim Connect wird

SET NAMES 'utf8'

ausgeführt. Warum erhalte ich dann jetzt aber nur beim ersten SELECT ein
Ergebnis?

SELECT name_de FROM object WHERE name_de LIKE 'teßt'
SELECT name_de FROM object WHERE name_de LIKE 'tesst'

Im Gegensatz dazu liefern diese beiden Anfragen Ergebnisse:

SELECT name_de FROM object WHERE name_de = 'teßt'
SELECT name_de FROM object WHERE name_de = 'tesst'

Warum funktioniert das bei LIKE nicht?

Gibt es dafür eine Lösung? Sollte ich LIKE-Anfragen in reguläre Ausdrücke
umformen und alle Vorkommen von 'ss' und 'ß' nach (ss|ß) umwandeln?

Schöne Grüße, Steffen

Re: latin1_german2_ci, utf-8

am 21.05.2006 00:15:14 von Axel Schwenke

"steffen horst" wrote:
>
> Warum erhalte ich dann jetzt aber nur beim ersten SELECT ein
> Ergebnis?
>
> SELECT name_de FROM object WHERE name_de LIKE 'teßt'
> SELECT name_de FROM object WHERE name_de LIKE 'tesst'
>
> Im Gegensatz dazu liefern diese beiden Anfragen Ergebnisse:
>
> SELECT name_de FROM object WHERE name_de = 'teßt'
> SELECT name_de FROM object WHERE name_de = 'tesst'
>
> Warum funktioniert das bei LIKE nicht?

Laut Handbuch [1] vergleicht LIKE zeichenweise. Damit funktionieren
Äquivalenzen mit unterschiedlicher Anzahl Zeichen nicht. Beispiel:

'ä' LIKE 'ae' COLLATE latin1_german2_ci -> 0
aber
'ü' LIKE 'y' COLLATE latin1_swedish_ci -> 1

Abhilfe weiß ich leider keine.

[1] http://dev.mysql.com/doc/refman/5.0/en/string-comparison-fun ctions.html


XL

Re: latin1_german2_ci, utf-8

am 21.05.2006 19:32:13 von steffen horst

hallo,

> Laut Handbuch [1] vergleicht LIKE zeichenweise. Damit funktionieren
> Äquivalenzen mit unterschiedlicher Anzahl Zeichen nicht. Beispiel:

> Abhilfe weiß ich leider keine.

Die Umformung in REGEXP funkioniert wohl.

1. Zeichen im Suchwort umformen:

'ss' => '(ss|ß)'
'ß' => '(ss|ß)'
'ü' => '(ü|ue)'
'ä' => '(ä|ae)'
'ö' => '(ö|oe)'
'ue' => '(ü|ue)'
'ae' => '(ä|ae)'
'oe' => '(ö|oe)'

2. Anfrage:

SELECT *
FROM


WHERE CONCAT_WS(' ', ) REGEXP '[[:<:]][[:>:]]'

Ich würde schätzen, es ist sinnvoller, die Spalten zunächst zu
konkatenieren, als den regulären Ausdruck auf die einzelnen Spalten
anzuwenden, oder?

Schöne Grüße, Steffen

Re: latin1_german2_ci, utf-8

am 21.05.2006 21:56:36 von Axel Schwenke

"steffen horst" wrote:
> hallo,
>
>> Laut Handbuch [1] vergleicht LIKE zeichenweise. Damit funktionieren
>> Äquivalenzen mit unterschiedlicher Anzahl Zeichen nicht. Beispiel:
>
>> Abhilfe weiß ich leider keine.
>
> Die Umformung in REGEXP funkioniert wohl.

Ja, nur wird dann kein Index verwendet. Wenn du WHERE ... LIKE ...
Ausdrücke hast, die Indizes verwenden *können* (also im Prinzip nur
rechts-trunkierte Suchmuster), dann könnte es eine Option sein, die
Daten in einer zweiten (redundanten) Spalte normiert abzulegen.

> WHERE CONCAT_WS(' ', ) REGEXP '[[:<:]][[:>:]]'
>
> Ich würde schätzen, es ist sinnvoller, die Spalten zunächst zu
> konkatenieren, als den regulären Ausdruck auf die einzelnen Spalten
> anzuwenden, oder?

Wenn du über mehrere Spalten suchen willst, dürfe ein FULLTEXT Index
die beste Variante sein. Da funktionieren dann auch Collations.


XL

Re: latin1_german2_ci, utf-8

am 22.05.2006 12:03:15 von steffen horst

> Ja, nur wird dann kein Index verwendet. Wenn du WHERE ... LIKE ...
> Ausdrücke hast, die Indizes verwenden *können* (also im Prinzip nur
> rechts-trunkierte Suchmuster), dann könnte es eine Option sein, die
> Daten in einer zweiten (redundanten) Spalte normiert abzulegen.

Da es sich voraussichtlich nur um ca. 1000 Zeilen handeln wird, ist es
eigentlich nicht schlimm, wenn kein Index verwendet wird.

>> WHERE CONCAT_WS(' ', ) REGEXP '[[:<:]][[:>:]]'
>> Ich würde schätzen, es ist sinnvoller, die Spalten zunächst zu
>> konkatenieren, als den regulären Ausdruck auf die einzelnen Spalten
>> anzuwenden, oder?
> Wenn du über mehrere Spalten suchen willst, dürfe ein FULLTEXT Index
> die beste Variante sein. Da funktionieren dann auch Collations.

Eigentlich wollte ich es zulassen, dass Wörter gefunden werden, die mit
dem Suchwort anfangen (' wort%') oder enden ('%wort '). [Ich hab das oben
verkürzt hingeschrieben.] Wie Du schon schriebst, beim Fulltext-Index
sind immerhin rechts-trunkierte Suchmuster möglich.

Kurz gesagt: Endweder schnelle Suche mit FULLTEXT-Index oder
mittels langsamen REGEXP zusätzliche Suchergebnisse, die mit dem Suchwort
enden.

Mischen lassen sich die beiden Ansätze auch nicht sinnvoll.

Vielen Dank für die Hilfe!

Schöne Grüße, Steffen