2013-04-18 41 views
18

Po prostu przeczytaj znakomitą odpowiedź Stefana Gehriga na Is "SET CHARACTER SET utf8" necessary?, która idzie nieco dalej niż dokumentacja MySQL wyjaśniająca etapy interpretowania i uruchamiania zapytania w.r.t. zestawy znaków i sortowania, ale nadal nie widzę celu funkcji character_set_connection, a dokładniej transkodowania instrukcji od character_set_client do character_set_connection.Jaki jest cel funkcji character_set_connection?

Dlaczego po prostu nie używać character_set_client dla zapytania i transkodowania prosto z character_set_client do zestawu znaków kolumny przy porównywaniu z wartościami kolumn? Jaki jest cel tego etapu pośredniego? Instrukcja podaje przykład porównywania literalnych żądań, ale dlaczego chcesz to zrobić na pierwszym miejscu, nie mówiąc już o character_set_connection jako przeciwstawiającej się character_set_client? Dopóki moje zrozumienie tego (coś w stylu "wybierz" somestr "=" somestr "od x") jest błędne.

Dziękuję.

+0

Możesz otrzymać niezadowalającą odpowiedź. Mógłbym być tak, że protokół sieciowy MySQL nie wspierał przesyłania kodowania używanego przez serwer, a zatem klient musiał wiedzieć, jak interpretować znaki przychodzące przez sieć i nie został złamany ze względu na kompatybilność. Zgaduję, to nie jest odpowiedź. – 0xCAFEBABE

+0

Dzięki za odpowiedź, a może nie rozumiem, ale myślę, że character_set_results służy do wysyłania wyników, a to jest wybierane przez klienta. O ile wiem z wyjaśnień, character_set_connection jest używane tylko wewnętrznie przez MySQL. – lm713

+0

Sądzę, że to właśnie MySQL użyje przy otrzymywaniu danych –

Odpowiedz

1

Obie są różne w tym character_set_client wyniesie charset oświadczenie jest wysyłane od klienta w, a zatem charset serwer używa interpretować oświadczenie, natomiast character_set_connection co serwer przetwarza oświadczenia w celu przetworzenia .

character_set_connection jest używany, jak to opisano, do porównywania łańcuchów literalnych. Nie musi to oznaczać, że obie strony równania muszą być dosłowne. Np .:

WHERE column_name = 'literal_string' 
    (charset col) (charset connection) 

Jeśli zestaw znaków kolumny i połączenie są różne, porównanie jest niezgodne z prawem i spowoduje błąd.

Wyniki (i komunikaty odpowiedzi) są następnie kodowane do character_set_results w celu odesłania do klienta.

+0

, ta odpowiedź nie mieści się w zasadniczej części pytania: dlaczego nie przekonwertować prosto z character_set_client? – goat

+1

Nie ma żadnej niejawnej konwersji podczas operacji porównania, dlatego etap pośredni jest konieczny w przypadku, gdy klient i serwer (kolumna) są w różnych zestawach znaków. – Hearth

+0

Zinterpretowałem pytanie z perspektywy programistów, dlaczego mamy tę dodatkową opcję i co ona robi? Jeśli chcesz zapytać filozoficznie, dlaczego serwer zachowuje się w sposób, w jaki działa, jest to prawdopodobnie najlepiej skierowane do zespołu deweloperskiego MySQL, ponieważ była to oczywiście decyzja projektowa w jakiejś sprawie. – Hearth

-1
> <?php 

// ... (create a connection to mysql) ... 

mysql_query("SET character_set_results = 'utf8', character_set_client = 'utf8', character_set_connection = 'utf8', character_set_database = 'utf8', character_set_server = 'utf8'", $conn); 

$re = mysql_query('SHOW VARIABLES LIKE "%character_set%";')or die(mysql_error()); 
while ($r = mysql_fetch_assoc($re)) 
{ 
    var_dump ($r); echo "<br />"; 
} 

exit; 

?> 

Wszystkie ważne zmienne są teraz UTF-8 i możemy bezpiecznie korzystać z wkładkami lub wybiera z mysql_escape_string ($ var) bez funkcji kodowania.

+0

Jeśli ustawisz zmienne połączenia za pomocą zapytań 'SET', ** nie możesz ** bezpiecznie korzystać z opcji po stronie klienta, a na pewno nie z' mysql_escape_string'. Musisz użyć 'mysql_set_charset()' po stronie klienta, a następnie użyć 'mysql_real_escape_string'. Lub zrezygnuj z wycofanego API mysql. – deceze

5

Po przeczytaniu odpowiedzi i dokumentacji, mogę myśleć tylko o jednym przypadku użycia do character_set_connection (i _collation):

wybierz "Stringa" < "StringB"

character_set_client tylko sprawy dotyczące przeniesienie na serwer. character_set_connection (i zestawianie, które nie jest niezależne od zestawu znaków) ma znaczenie dla interpretacji oświadczenia. To, czy "StringA" jest mniejsze niż "StringB", zależy od zestawu znaków i zestawienia literałów. Programista może wybrać zestaw znaków/sortowanie różniące się od character_set_client.

W praktyce, character_set_connection nie ma znaczenia w większości przypadków, ponieważ literały są porównywane z kolumnami, w którym to przypadku używa się zestawu znaków kolumny i sortowania.

Popraw mnie, jeśli się mylę!

Zobacz https://dev.mysql.com/doc/refman/5.0/en/charset-connection.html:

Co charakter zestaw powinien serwer tłumaczyć oświadczenie po otrzymania? W tym celu serwer używa zmiennych systemowych character_set_connection i collation_connection. Konwertuje wyciągnięte przez klienta instrukcje od klienta z character_set_client na character_set_connection (z wyjątkiem literałów łańcuchowych, które mają element wprowadzający, taki jak _latin1 lub _utf8). collation_connection jest ważne dla porównań literalnych ciągów znaków. W przypadku porównań łańcuchów z wartościami kolumn nie ma znaczenia, czy kolumny mają własne sortowanie , które ma wyższy priorytet sortowania.