2013-04-18 58 views
18

Chỉ cần đọc Stefan Gehrig câu trả lời tuyệt vời cho Is "SET CHARACTER SET utf8" necessary?, mà đi xa hơn một chút so với tài liệu của MySQL tại giải thích các giai đoạn diễn giải và chạy truy vấn w.r.t. bộ ký tự và collations, nhưng tôi vẫn không thể thực sự thấy mục đích của character_set_connection, hoặc cụ thể hơn chuyển mã câu lệnh từ character_set_client thành character_set_connection.Mục đích của character_set_connection là gì?

Tại sao không chỉ sử dụng character_set_client cho truy vấn và chuyển mã trực tiếp từ character_set_client thành tập ký tự của cột khi so sánh với giá trị cột? Mục đích của giai đoạn trung gian này là gì? Tài liệu hướng dẫn này đưa ra ví dụ về việc so sánh các bản in chữ, nhưng tại sao bạn lại muốn thực hiện điều này ngay từ đầu, hãy để một mình trong character_set_connection như trái ngược với character_set_client? Trừ khi sự hiểu biết của tôi về điều này (một cái gì đó như "chọn" somestr '=' somestr 'từ x ") là sai.

Cảm ơn bạn.

+0

Bạn có thể nhận được câu trả lời không thỏa đáng. Tôi rất có thể là giao thức mạng MySQL không hỗ trợ chuyển máy chủ được sử dụng mã hóa và cho khách hàng cần biết cách diễn giải các ký tự đến trên mạng và nó không bị hỏng vì lý do tương thích. Tôi đoán, đây không phải là câu trả lời. – 0xCAFEBABE

+0

Cảm ơn bạn đã trả lời, và có lẽ tôi không hiểu, nhưng tôi nghĩ rằng character_set_results được sử dụng để gửi kết quả và điều này được chọn bởi khách hàng. Theo như tôi biết từ các giải thích, character_set_connection chỉ được sử dụng nội bộ bởi MySQL. – lm713

+0

Tôi tin rằng đây là những gì MySQL sẽ sử dụng khi nhận dữ liệu –

Trả lời

1

Hai khác biệt trong đó character_set_client được giả định là bộ ký tự câu lệnh được gửi từ máy khách và do đó bộ mã mà máy chủ sử dụng để diễn giải câu lệnh, trong khi character_set_connection là những gì máy chủ chuyển đổi câu lệnh thành để xử lý .

character_set_connection được sử dụng, như được thảo luận, để so sánh các chuỗi chữ. Điều này không cần thiết có nghĩa là cả hai mặt của phương trình phải là chuỗi ký tự bằng chữ. Ví dụ:

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

Nếu bộ ký tự của cột và kết nối khác nhau, so sánh là bất hợp pháp và sẽ gây ra lỗi.

Kết quả (và thông báo phản hồi) sau đó được mã hóa thành character_set_results để gửi lại cho khách hàng.

+0

câu trả lời này bỏ qua phần quan trọng của câu hỏi: tại sao không chuyển đổi trực tiếp từ character_set_client? – goat

+1

Không có chuyển đổi ngầm trong quá trình so sánh, do đó, giai đoạn trung gian là cần thiết trong trường hợp máy khách và máy chủ (cột) nằm trong các bộ ký tự khác nhau. – Hearth

+0

Tôi giải thích câu hỏi là từ quan điểm của nhà phát triển vì sao chúng ta có tùy chọn bổ sung này và nó làm gì? Nếu bạn muốn hỏi về mặt lý thuyết tại sao máy chủ hoạt động theo cách thức của nó, đó có lẽ là hướng tốt nhất tại nhóm dev MySQL, vì nó rõ ràng là một quyết định thiết kế ở một số satge. – Hearth

0

Đó là vì MySQL cho phép mọi chuỗi ký tự có bộ ký tự riêng. Điều đó nói rằng, bộ ký tự của chuỗi ký tự trong một câu lệnh không phải lúc nào cũng giống như câu lệnh.

Xem trang này trong cuốn hướng dẫn: http://dev.mysql.com/doc/refman/5.5/en/charset-literal.html

-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; 

?> 

Tất cả các biến quan trọng bây giờ là utf-8 và chúng ta có thể an toàn sử dụng BIG hoặc chọn với mysql_escape_string ($ var) mà không cần bất kỳ chức năng mã hóa.

+0

Nếu bạn đặt các biến kết nối thông qua các truy vấn 'SET', bạn ** không thể ** sử dụng thoát an toàn phía máy khách và chắc chắn không phải với' mysql_escape_string'. Bạn cần sử dụng phía máy khách 'mysql_set_charset()' và sau đó sử dụng 'mysql_real_escape_string'. Hoặc từ bỏ API mysql không dùng nữa để bắt đầu. – deceze

5

Sau khi đọc câu trả lời và tài liệu hướng dẫn, tôi chỉ có thể nghĩ đến một trường hợp sử dụng cho character_set_connection (và _collation):

CHỌN "StringA" < "StringB"

character_set_client chỉ vấn đề cho chuyển đến máy chủ. character_set_connection (và đối chiếu, không độc lập với bộ ký tự) quan trọng cho việc giải thích của tuyên bố. Cho dù "StringA" là nhỏ hơn "StringB" phụ thuộc vào bộ ký tự và collation của literals. Một nhà phát triển có thể chọn một bộ ký tự/collation khác với character_set_client.

Trong thực tế, character_set_connection không phải là vấn đề phần lớn thời gian, bởi vì các chữ được so sánh với các cột, trong trường hợp này, bảng mã và collation của cột được sử dụng.

Đúng nếu tôi sai!

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

bộ ký tự gì nên máy chủ dịch một tuyên bố sau khi nhận nó? Đối với điều này, máy chủ sử dụng các biến hệ thống character_set_connection và collation_connection. Nó chuyển đổi các câu lệnh được gửi bởi khách hàng từ character_set_client đến character_set_connection (ngoại trừ các chuỗi ký tự có một người giới thiệu như _latin1 hoặc _utf8). collation_connection là quan trọng để so sánh các chuỗi chữ. Để so sánh các chuỗi có giá trị cột, collation_connection không quan trọng bởi vì các cột có số collation riêng, có tỷ lệ đối chiếu cao hơn.

Các vấn đề liên quan