vet0, o 03 listopad 2011 - 20:54, powiedział:
A jest w ogole jakieś kodowanie w którym mysql zapisuje w tabelach polskie litery tak jak powinno być ? o chyba nie.. Każde kodowanie z jakim się spotkałem zastępuje znaki diakrytyczne jakimiś krzaczorami

Doskonały przykład niezrozumienia problemu. Kafi, pisz ten tutorial
Nie ma czegoś takiego jak "tak jak powinno być". Musisz rozróżnić dwie kluczowe sprawy: znaki a bajty (Unicode ninjas są proszeni o przymknięcie oczu na drastyczne uproszczenia). Masz taki znaczek: "ą" (LATIN SMALL LETTER A WITH OGONEK). W bazie Unicode ma on przypisany kod U+0105 i tyle możesz o nim powiedzieć. Niestety, codepointów (czyli np. takich U+0105) nie da się bezpośrednio zapisać w bazie danych, wysłać w sieć itp., dlatego powstały różne sposoby konwersji znaków (LATIN SMALL...) na bajty. Realnie używany jest UTF-8, gdzie ą (U+0105) jest zapisywane jako dwa bajty: \xc4 \x85. Proces dekodowania UTF-8 -> Unicode zamienia z powrotem te dwa bajty na U+0105, czyli platoniczny ideał "ą".
Zanim upowszechnił się Unicode i UTF-8, powszechne były inne, jednobajtowe kodowania (i niestety dalej są powszechnie używane). Np. w popularnym ISO-8859-2 znak ą (wtedy jeszcze nie był ani LATIN SMALL..., ani tym bardziej U+0105) zapisuje się jako jeden bajt \xb1. W forsowanym onegdaj przez MS kodowaniu CP-1250 ą to \xb9. Wszystkie te zapisy opisują dokładnie ten sam znak: ą, ale żeby się tego dowiedzieć, musisz wiedzieć, jakiego kodowania użyć do konwersji \xb9 -> Unicode. Bo \xb9 to wcale nie musi być ą w CP-1250, to równie dobrze może być š w ISO-8859-2.
"Krzaki" pojawiają się, kiedy traktujesz dane zapisane w jednym kodowaniu jako zapisane w innym. Przykładowo, masz string "\xb1", który (jesteś o tym głęboko przekonany) przedstawia ą w latin2 (ISO-8859-2). Twój software operuje w UTF-8, jak Latający Potwór Spaghetti przykazał, więc przed wyświetleniem (wypisaniem do przeglądarki) musi przekonwertować ten string na UTF-8. Tak się nieszczęśliwie składa, że skądś sobie wydumał, że ten string jest zakodowany w latin1 (ISO-8859-1). No to bierze \xb9 i konwertuje latin1->UTF8. Wynik? \xc2 \xb1, odpowiadający U+00B1, czyli PLUS-MINUS SIGN (±).
Druga warstwa konwersji, która również musi się udać żeby było widać pliterki a nie krzaki, to wyświetlanie. Tutaj ponownie konwertowane są dane z postaci strumienia bajtów z określonym kodowaniem (wynikającym z nagłówków http, ustawień terminala czy czego tam innego), a wynikowe codepointy są odnajdowane w fontach i rysowane na ekranie.
Problem jest szczególnie widoczny w mysqlu (zwłaszcza za czasów migracji 4.0->4.1 to była prawdziwa plaga), bo łatwo jest osiągnąć konfigurację, która prawie zawsze działa. Przykładowo: na stronie zadeklarowane kodowanie utf8, dane do bazy wrzucane zakodowane również w utf8, a kodowanie kolumny w bazie i oczekiwane kodowanie danych wyjściowych zadeklarowane jako latin1 (domyślne). Wygląda to tak:
1. User w formularzu wpisuje ą
2. Przeglądarka wysyła \xc4 \x85
3. INSERT INTO ... VALUES (..., "\xc4\x85")
4. Serwer mysql konwertuje dane z latin1 (character_set_client się ta opcja bodajże nazywa) do latin1 (kodowanie kolumny), czyli nic nie robi
5. SELECT ... FROM ...
6. Serwer mysql konwertuje dane z latin1 (kodowanie kolumny) do latin1 (character_set_client), czyli nic nie robi
7. Do klienta idzie \xc4 \x85 z nagłówkiem "Content-type: text/html; charset=utf-8"
8. Klient dekoduje \xc4 \x85 na U+0105 i wyświetla ą
Teraz puszczamy w to wszystko phpmyadmina, który stara się robić dobrze i eksportować dane w utf8:
0. SET NAMES UTF8
1. SELECT ... FROM ...
2. Serwer mysql konwertuje dane z latin1 (kodowanie kolumny) do utf8 (character_set_client)
3. Klient dostaje wynik konwersji \xc4 (LATIN CAPITAL LETTER A WITH DIAERESIS, \xc3 \x84) i \x85 (NEXT LINE, \xc2 \x85)
4. OMGWTFBBQ gdzie moje ogonki?