Pomoc - Szukaj - Użytkownicy - Kalendarz
Pełna wersja: Dwie różne metody porównywania napisów
Forum PHP.pl > Forum > Bazy danych > MySQL
markonix
Mam duży portal wielojęzyczny i oczywiście kodowanie UTF-8.
Niestety w MySql ten wybór nie jest taki oczywisty bo mamy go wiele odmian.

Do wyboru są wg mnie dwa:
utf8_unicode_ci i utf8_general_ci

Ten pierwszy jest lepszy jeżeli chodzi np. o sortowanie z polskimi znakami (osoby typu Łukasz nie lądują na końcu) ale w jakimś tam stopniu jest wolniejszy.
Zastanawiam się czy nie byłoby ciekawą ideą aby stosować te powyższe kodowania zamiennie - unicode w przypadku tabel z nazwami własnymi, a general tylko do tabel "zamkniętych" (tabele ustawień, wyniki, relacje, po prostu tabele gdzie są tylko liczby i krótkie stringi po angielsku).

Czy taka zabawa jest warta świeczki i nie wywoła błędu z "Illegal mix of collations"?
Lepiej sobie darować i lecieć w jednym?
Jeżeli jednak mieszać to jakie powinno być kodowanie główne (całej bazy - chyba, że to nie ma większego znaczenia i jest tylko po prostu domyślnym kodowaniem dla tabel w bazie).
markonix
Cytat(viking @ 30.07.2012, 16:27:00 ) *


Jaki związek z moim pytaniem ma tutorial o tworzeniu tabel z odpowiednim kodowaniem?
darko
http://forums.mysql.com/read.php?103,18704...8748#msg-188748 W skrócie: jeśli chcesz poprawnie sortować dane to użyj utf8_unicode_ci, jeśli zależy Ci na wydajności i szybkości wyszukiwania danych - użyj utf8_general_ci.
Crozin
1. Jeżeli dla danej kolumny nie będziesz w ogóle stosować porównań (pamiętaj, że dotyczy to również sortowań), będziesz przechowywać tam jedynie znaki łacińskie bądź będziesz wykonywać dokładne porównania (np. dla kolumny z slugiem nazwy użytkownika, bądź kluczem jakiejś opcji konfiguracyjnej) możesz korzystać z binarnej metody porównywania znaków (utf8_bin).
2. "Ł" na końcu listy przy utf8_unicode_ci to bug MySQL-a, którego chyba nigdy nie poprawią albo w ogóle nie chcą poprawić - nie pamiętam, wiem że jest zgłoszone na bugtracku MySQLa.
3. Pamiętaj, że metoda porównywania znaków może zostać określona na poziomie zapytania SQL:
  1. SELECT ... ORDER BY col_name COLLATE utf8_unicode_ci ...;
I nie będzie to miało żadnego wpływu na prędkość wykonywania zapytania.
viking
Cytat(markonix @ 30.07.2012, 16:44:24 ) *
Jaki związek z moim pytaniem ma tutorial o tworzeniu tabel z odpowiednim kodowaniem?

Taka że nie wiem czy wiesz ale porównywanie istnieje nie tylko dla całych tabel ale również na poziomie kolumn. Teraz dopowiedz sobie co możesz z tym dalej zrobić żeby to miało wpływ na wydajność (nawet w kontekście twoich słów). A najlepszą opcją jest przestać używać mysql wink.gif
markonix
Cytat(darko @ 30.07.2012, 16:51:26 ) *
http://forums.mysql.com/read.php?103,18704...8748#msg-188748 W skrócie: jeśli chcesz poprawnie sortować dane to użyj utf8_unicode_ci, jeśli zależy Ci na wydajności i szybkości wyszukiwania danych - użyj utf8_general_ci.

Mniej więcej te różnice znam, chodzi o mieszanie tych dwóch kodowań jednocześnie w obrębie jednej aplikacji.

Cytat(Crozin @ 30.07.2012, 17:14:23 ) *
1. Jeżeli dla danej kolumny nie będziesz w ogóle stosować porównań (pamiętaj, że dotyczy to również sortowań), będziesz przechowywać tam jedynie znaki łacińskie bądź będziesz wykonywać dokładne porównania (np. dla kolumny z slugiem nazwy użytkownika, bądź kluczem jakiejś opcji konfiguracyjnej) możesz korzystać z binarnej metody porównywania znaków (utf8_bin).
2. "Ł" na końcu listy przy utf8_unicode_ci to bug MySQL-a, którego chyba nigdy nie poprawią albo w ogóle nie chcą poprawić - nie pamiętam, wiem że jest zgłoszone na bugtracku MySQLa.
3. Pamiętaj, że metoda porównywania znaków może zostać określona na poziomie zapytania SQL:
  1. SELECT ... ORDER BY col_name COLLATE utf8_unicode_ci ...;
I nie będzie to miało żadnego wpływu na prędkość wykonywania zapytania.

1. O bin nawet nie myślałem, będzie z tego jaka konkretna korzyść w porównaniu do general?
2. Coś teraz mi też zaświeciło z samą literą ł. W każdym razie imię Łukasz nie było celowe, chodziło ogólnie o polskie znaki na początku i unicode posortuje dobrze, general już nie.

Edit:

Teraz już się pogubiłem:
Kod
agew
śadmin
stest
testt
zfgerer
źregerge

Dla utf8_general_ci. Posortowało dobrze..
Crozin
Cytat
1. O bin nawet nie myślałem, będzie z tego jaka konkretna korzyść w porównaniu do general?
Musiałbyś sprawdzić, jakąś tam korzyść przyniesie, pytanie tylko czy wymierną. Pamiętaj, że w przeciwieństwie do kodowania znaków system porównywania znaków można w każdej chwili bezproblemowo zmienić.

Generalnie używaj utf8_unicode_ci - ma nieco lepszą dokładność od utf8_general_ci, a koszt tej dokładności jest raczej niewielki. Bug z literką "Ł" jest nie do przeskoczenia - chyba, że samodzielnie poprawisz sobie w źródłach i MySQL skompilujesz ;] - i w 99% przypadków poza kłuciem po oczach w niczym nie przeszkadza.
markonix
Cytat(Crozin @ 30.07.2012, 20:23:04 ) *
Pamiętaj, że w przeciwieństwie do kodowania znaków system porównywania znaków można w każdej chwili bezproblemowo zmienić.


Żeby masowo zmienić to trzeba by było chyba procedurę pisać albo w PHP skrypt.
Crozin
Chodziło mi o to, że mając już działająca pod jakimś tam obciążeniem bazę danych mógłbyś sprawdzić czy zmiana z utf8_unicode_ci na utf8_bin (czy nawet samo binary) przyniesie realną korzyść.

A co do masowej zmiany, nie wiem czy nie wystarczyłoby w information_schema.COLUMNS i ewnetualnie information_schema.TABLES zmienić i zrestartować serwer MySQL. Zresztą skrypt/procedura robiąca to będzie miała 10 linijek kodu, więc to bez znaczenia.
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.