JustPaste.it

Polskie ogonki w MySQL

Polskie znaczki ąęćł... czasami dają w kość. Jak dać sobie z nimi radę?

Polskie znaczki ąęćł... czasami dają w kość. Jak dać sobie z nimi radę?

 

Polskie znaczki ąęćł... czasami dają w kość. Zapisujesz coś do bazy danych, a po przeniesieniu na inny serwer wszystko się “wykrzacza” i czeka cię mozolne poprawianie  treści lub wielokrotne próby eksportu i importu danych między bazami. MySQL to jeden z popularniejszych serwerów baz danych. Na wielu forach joomlowych czy mysqlowych widziałem powtarzające się pytania na temat zapisu do baz polskich liter diakrytycznych, które niespodziewanie się gubią. Oto kilka  wyjaśnień dotyczących tego tematu.

Character set to standard kodowania znaków, czyli jakim kodom numerycznym odpowiadają jakie znaki, collation to system porównań znaków, nie ma on wpływu na “gubienie” polskich ogonków.
MySQL to baza typu client-serwer , w której klient łączy się z bazą poprzez nawiązane połączenie. Klientem bazy może być na przykład joomla, może to być klient terminalowy, a może być także narzędzie do zarządzania bazą takie jak phpmyadmin.
Klient MySQL, który koduje znaki w standardzie character_set_client śle zapytanie, poprzez połączenie. Kodowanie znaków dla połączenia określone są przez zmienną character_set_connection. - jest to standard na jaki należy przekonwertować zestaw znaków zapytania. Konwersja jednak następuje tylko wtedy gdy oba standardy są różne.
Tak przekonwertowane teksty zapisywane są do bazy, która ma zdefiniowany swój własny zestaw znaków character_set_database. Jeśli poprzez połączenie przekonwertowaliśmy znaki na inny standard niż standard bazy to możemy spodziewać zgubienia polskich znaków, jeśli z bazy zechcemy coś wydobyć. Rezultat zapytania bowiem konwertowany jest do standardu character_set_result, ze standardu character_set_database bazy. Oczywiście dobrze by było aby rezultat zapytania, który jest wysyłany z powrotem do klienta był kodowany tak samo jak zapytanie do bazy, czyli aby character_set_result i character_set_client były takie same.
Poniższy schemat przedstawia sposób zapisu do bazy i odczytu z niej danych oraz pokazuje zmienne systemowe przechowujące informacje o standardach kodowania znaków.

Image

Jakie jest najkorzystniejsze ustawienie zmiennych dotyczących zestawów znaków? Oczywiście takie, aby połączenie i serwer nie musiały wykonywać żadnych konwersji. Poniższy schemat przedstawia taki przypadek – wszystkie zmienne ustawione są na latin2.

Image

Domyślna instalacja serwera MySQL ustawia zestaw znaków dla niego na latin1 (nic dziwnego – Szwecja to ojczyzna MySQL ), co sprawia, że domyślnie standard kodowania nowo tworzonych baz to latin1. Zwykle tutaj pojawiają się problemy. Gdy chcemy zapisywać polskie teksty, baza i klient mają wtedy inne zestawy znaków. Jak ustawić zmienne gdy założona baza danych kodowana jest latin1, a klient używa latin2 przedstawia poniższy schemat.

Image

Klient terminalowy MySQL
Używając klienta terminalowego możemy łatwo sprawdzić ustawienia zmiennych serwera.

SHOW VARIABLES LIKE “CHARACTER%”

Powyższa komenda wylistuje nam wszystkie zmienne zaczynające się od łańcucha CHARACTER.
Poza logowaniu się do bazy, możemy więc sprawdzić jak zdefiniowana została nasza baza: character_set_database oraz aktualne zmienne ustawienia klienta i połączenia.
Do zmiany ustawień tych zmiennych służą polecenia:

SET NAMES ‘strona_kodowa’;

Ustawia ona trzy zmienne: character_set_client, character_set_connection i character_set_result na wartość podaną jako parametr (w apostrofach).

SET CHARACTER SET strona_kodowa;

Jest to chyba bardziej przydatna komenda, gdyż ustawia ona character_set_client i character_set_result na podaną stronę kodową oraz character_set_connection ustawia na taką samą wartość jak strona kodowa bazy character_set_database. Czyli, po użyciu tej komendy, mamy klienta ustawionego na wybraną przez nas stronę zarówno dla zaptytań jak i wyników zwracanych przez bazę. Mamy także zestaw znaków dla połączenia ustawiony zgodnie ze stroną kodową bazy, czyli przekonwertowane łańcuchy prawidłowo będą zapisywać się do bazy.

PhpMyAdmin
Jest to narzędzie, którym możemy zarządzać bazą przez przeglądarkę internetową. Niestety, żadna z powyżej opisanych komend terminalowych nie działa (oprócz SHOW VARIABLES). Ustawienia zestawów znaków przestawia się przez zmianę dwóch list wyboru: Język i System porównań dla połączenia MySQL. System porównań to oczywiście wcześniej wspomniane collation, które nie powinno wpływać na zapisy i odczyty znaków do baz, a na ich sortowanie. Ale w phpMyAdminie zmieniając collation zmieniamy także charset. W wypadku listy: System porównań dla połączenia MySQL zmienia się character_set_connection. Wybór z drugiej listy: Język - zmienia ustawienia klienta.

Joomla
W Joomli możliwość ustawienia zestawu znaków dla klienta i połączenia mamy w pliku configuracyjnym ( ./includes/database.php ) w linii

//@mysql_query(“SET NAMES 'utf8'”, $this->_resource);



Aby ustawić wybrany zestaw znaków, trzeba usunąć znaki komentarza na początku linii i wpisać ten zestaw w apostrofy, gdzie w przykładzie powyżej jest wpisane utf8. Zwykle wpisujemy tam latin2.

Reasumując, poprawne ustawienie zestawu znaków nie jest trudną sprawą, ale wymaga przemyślenia, najlepiej przed dokonaniem zapisów do bazy. Teksty zapisane do baz przy błędnych ustawieniach zazwyczaj wymagają żmudnego ręcznego “przestukania” lub edycji, metodą znajdź – zamień, zrzuconych do plików tekstowych baz. Myślę, że powyższe wyjaśnienia pomogą wszystkim tym, którzy szukają zagubionych "ogonków" w swoich bazach.

Dodatkowe informacje na stronach:
http://dev.mysql.com/doc/
http://help.joomla.org/

Zmieniony ( 31.01.2007. )

Przedruk dokonany za zgodą autora 

 

Źródło: Jurek