Pomoc - Szukaj - Użytkownicy - Kalendarz
Pełna wersja: Wyszukiwanie w bazie polskich liter
Forum PHP.pl > Forum > Bazy danych > MySQL
pgrzelka
Witam

mam w bazie rekordy

Łódź
Będzin
Fläming
itd...

ogólnie lista miast z całej europy

teraz chcę wyszukać w tej bazie za pomocą LIKE %% np.
'odz' - znajdzie Łódź
'fla' - znajdzie Fläming
'Lod' - czemu nie znajduje 'Ł' jeśli w LIKE damy 'L'? tylko z tą literą jest problem

kodowanie w tabeli to utf_general_ci, ogólnie wszystko jest ustawione na utf_general_ci

czy zna ktoś rozwiązanie mojego problemu?
pmir13
Rozwiązaniem jest stworzenie własnego collate, obejdzie się bez kompilowania mysql, chociaż źródła się mogą przydać by skopiować utf_general_ci i tylko zmiany wprowadzić. Oczywiście trzeba mieć nieco lepszy dostęp do serwera niż standardowy hosting. W odpowiednim pliku xml można zdefiniować taki collate, w którym Ł i ł wejdą do L, ut8_general_ci jest najbliżej wspólnego ładowania wszystkich ogonków z europejskich języków w podstawowe litery, ale akurat Ł i ł mają osobną wagę.
achill
witam
mam podobny problem.
choć chodzi mi o cos wręcz odwrotnego.
to znaczy mam w bazie dajmy na to 'Łódź'
i chciałbym zeby po zapytaniu do bazy o tresci 'Lodz' nie wyrzucało rekordów z wartością Łódź.

ten przykład jest chyba ciut nietrafiony, zatem inny

mam w bazie kancelarię oraz administrację (obsługa mieszkańców)
przy cząstkowym (tylko czesc nazwy) zapytaniu o te które w nazwie maja kanc wyrzuca mi jako wyniki
kancelarie
oraz
mieszkańców

stosuje w zapytaniu do mysqla :
  1. SELECT wartosc='%zapytanie%' FROM tabela

formatownie bazy to jak u kolegi utf_general_ci

Czy ktos mógłby mi zaproponować jak rozwiązać taki problem:

oczywiście jest pewna możliwość - w php juz po pobraniu wyników przefiltrowac dane i pozwolic wyswitlic tylko te które naprawde spełniają zapytanie, rzecz w tym, że takie rozwiązanie ma dwie wady:
- dodatkowy kod, ktory ma poprawiać co wykonał mysql - co samo w sobie jest już bezsensu bo po co robic dwa razy to samo
- baza zwraca wyniki, ktore nastepnie selekcjonuje, po co, obciazam niepotrzebnie baze, serwer, łącze itd itp
W związku z powyższym odpada.

Zatem trzeba szukac w mysqlu.
Drugim moim pomyslem było zastosowanie innego kodowania - pytanie ktorego? w końcu chcę aby polskie znaki tez były używane.
czy zatem istnieje jakies kodowanie które posiada polskie znaki ale nie traktuje ł jak l lub ź jak z - i vice versa.
Rozumiem że Collate może tu dużo zdziałać.
Przyznaję jednak, że nie znam na tyle dobrze mysqla aby sobie ot tak zmieniać bezbłednie kodowania.

1 - rozumiem że COLLATE zamienia kodowanie na czas wykonywania zapytania (tak rozumiem to co napisali w manualu :With the COLLATE clause, you can override whatever the default collation is for a comparison.)? comparison? to przecież porównanie? czy ktoś mógłby mi wytłumaczyć tak po ludzku jak to właściwie działa całe to COLLATE.
2 - dajmy na to jesli wyszukuje przez zapytanie typu (przykład z manuala)
  1. SELECT k COLLATE latin1_german2_ci AS k1
  2. FROM t1

a baze mam w utf_general_ci - to czy nie wywoła to błedów?
3 - jakie kodowanie - utf8_polish_ci?
4- czy ktos zna jakies dobre opracowanie do kodowan z mysqla, prosze o linka?

ps. problem jest juz właściwie teoretyczny bo po uwzględeniu, że uzytkownik może nieumyslnie zrobic błąd w czasie wpisywanie zapytania, nie będę takiej funkcji wprowadzał. (wiadoma sprawa literówki itp)

Pomyślałem jednak, że temat jest ciekawy i byc może komuś takie wyszukiwanie może się przydać.
pmir13
Collate to nie jest sposób kodowania, nie definiuje nam jak binarnie reprezentowane są znaki, definiuje nam natomiast wagę każdego znaku, która służy do sortowania, porównywania itp. Przykładowo
  1. SELECT 'N' LIKE 'Ń' collate utf8_polish_ci
zwraca 0, bo wg tego collate litera Ń jest następną po N, natomiast jeśli spróbujemy
  1. SELECT 'N' LIKE 'Ń' collate utf8_general_ci
to dostajemy 1, bo ten collate traktuje Ń jako akcent litery N i wrzuca do tej samej wagi w kolejności alfabetycznej. Wszystko dzieje się w obrębie tego samego kodowania znaków - UTF8.
achill
czyli
1 - utf8_polish_ci - powinien wystarczyć do takiego porównywania znaków.
2 - calosc nadal pracuje na utf8_general_ci, tzn pobiera wartosc wg tego kodowania i jako taka bedzie przeslana do wyników, ale sama operacja like, = i inne tego typu sa sprawdzane pod katem zbiezności z kodowaniem podanym przez collate?

jesli wiec dobrze zrozumiałem
dla troche innego przykładu:

  1. SELECT 'a' LIKE 'ą' collate utf8_polish_ci


da 0 bo (tak to rozumiem a różne od ą) 'a' to pierwsza litera alfabetu, podczas gdy 'ą' juz drugą.
W general_ci z kolei obie sa traktowane jako pierwsza litera alfabetu?

ok jeśli dobrze to rozumiem to wydaje się to jasne (i o dziwo proste - spodziewałem się czegos bardziej skomplikowanego).
Dzięki wielkie, to wiele wyjasniło.


LBula
Cytat(pmir13 @ 6.05.2011, 21:29:24 ) *
Rozwiązaniem jest stworzenie własnego collate, obejdzie się bez kompilowania mysql, chociaż źródła się mogą przydać by skopiować utf_general_ci i tylko zmiany wprowadzić. Oczywiście trzeba mieć nieco lepszy dostęp do serwera niż standardowy hosting. W odpowiednim pliku xml można zdefiniować taki collate, w którym Ł i ł wejdą do L, ut8_general_ci jest najbliżej wspólnego ładowania wszystkich ogonków z europejskich języków w podstawowe litery, ale akurat Ł i ł mają osobną wagę.


Mam prośbę o rozwinięcie w/w post'a. Wydaje mi się, że z uwagi na to, że MySQL nie uznał tego za bug i od kilku lat nic się w tym temacie nie zmieniło jest to jedyne słuszne rozwiązanie problemu. Mam pełny dostęp do serwera i opisany problem z literą "ł". Rozumiem, że chodzi o rozwiązanie opisane tutaj:

http://dev.mysql.com/doc/refman/5.0/en/add...imple-8bit.html

W pliku Index.xml kodowanie utf8_general_ci (bo domyślam się, że to kodowanie miałeś na myśli i pominąłeś 8) ma flagę 'compiled', w związku z tym nie ma osobnego pliku xml z opisem mapy jak w przypadku ascii, latin1, latin2 itd.

W pliku README w katalogu charsets w którym znajdują się w/w pliki xml w odpowiedzi na pytanie "When should a character set be compiled in to MySQL's string library (libmystrings), and when should it be placed in a charset_name.xml configuration file?" otrzymujemy odpowiedź "If the character set requires the strcoll functions or is a multi-byte character set, it MUST be compiled in to the string library. If it does not require these functions, it should be placed in a charset_name.xml configuration file.". Rozumiem, że skoro utf-8 jest multi-byte to nie da się podmienić działania collate utf8_general_ci dla litery "ł" bez rekompilacji MySQL?

Na stronie MySQL'a możemy jeszcze przeczytać coś takiego:

http://dev.mysql.com/doc/refman/5.0/en/add...nicode-uca.html

Ma ktoś pomysł jak poradzić sobie z tym problemem?
To jest wersja lo-fi głównej zawartości. Aby zobaczyć pełną wersję z większą zawartością, obrazkami i formatowaniem proszę kliknij tutaj.
Invision Power Board © 2001-2025 Invision Power Services, Inc.