2013-04-18 32 views
18

剛剛閱讀Stefan Gehrig對Is "SET CHARACTER SET utf8" necessary?的優秀回答,它比MySQL的文檔更詳細地解釋瞭解釋和運行查詢的幾個階段w.r.t.字符集和歸類,但我仍然無法真正看到character_set_connection的用途,或者更具體地說,將character_set_client中的語句轉碼爲character_set_connection。character_set_connection的用途是什麼?

爲什麼不直接使用character_set_client進行查詢,並在與列值比較時直接從character_set_client轉換爲字符集的字符集?這個中間階段的目的是什麼?這本手冊給出了比較字面刺激的例子,但爲什麼你要這樣做,更不用說在character_set_connection中與character_set_client相對立呢?除非我對此的理解(例如「select'somestr'='somestr'from x」)是錯誤的。

謝謝。

+0

您可能會得到不滿意的答案。我很可能是因爲MySQL網絡協議不支持傳輸服務器使用的編碼,因此客戶端需要知道如何解釋通過網絡傳來的字符,並且由於兼容性的原因它尚未被破壞。我只是猜測,這不是一個答案。 – 0xCAFEBABE

+0

感謝您的回覆,也許我不明白,但我認爲character_set_results用於發送結果,並由客戶端選擇。據我所知,解釋中,character_set_connection只在MySQL內部使用。 – lm713

+0

我相信這是MySQL在接收數據時會用到的東西 –

回答

1

這兩者不同之處在於character_set_client被假定爲從客戶端發送語句的字符集,因此服務器使用字符集來解釋語句,而character_set_connection是服務器將語句轉換爲用於處理的內容。

character_set_connection用於比較文字字符串,如上所述。然而,這並不意味着方程的兩邊都必須是文字字符串。例如:

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

如果字符集的列和連接的是不同的,比較是非法的,並會導致錯誤。

然後將結果(和和響應消息)編碼爲character_set_results以發送回客戶端。

+0

這個答案錯過了問題的關鍵部分:爲什麼不直接從character_set_client轉換? – goat

+1

比較操作期間沒有隱式轉換,因此如果客戶端和服務器(列)使用不同的字符集,中間階段是必需的。 – Hearth

+0

我從開發人員的角度解釋了這個問題,爲什麼我們有這個額外的選項,它有什麼作用?如果你想問哲學上爲什麼服務器的行爲方式如此,那麼這可能是針對MySQL開發團隊的最好方式,因爲它顯然是在某個舞臺上的設計決策。 – 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; 

?> 

所有重要的變量現在UTF-8,我們可以不進行任何編碼功能,安全使用的INSERT或選擇與函數mysql_escape_string($ VAR)。

+0

如果通過'SET'查詢來設置連接變量,那麼**不能**安全地使用客戶端轉義,並且絕對不能使用'mysql_escape_string'。你需要使用'mysql_set_charset()'客戶端,然後使用'mysql_real_escape_string'。或者放棄不推薦使用的mysql API。 – deceze

5

閱讀的答案和文件之後,我只能想到一個用例的character_set_connection(和_collation):

SELECT 「StringA」 < 「StringB」

character_set_client僅供事項轉移到服務器。 character_set_connection(以及不與字符集獨立的歸類)對語句的解釋很重要。 「StringA」是否小於「StringB」取決於文字的字符集和整理。開發人員可能會選擇與character_set_client不同的字符集/排序規則。

實際上,大多數情況下,character_set_connection並不重要,因爲文字與列進行比較,在這種情況下使用列的字符集和歸類。

糾正我,如果我錯了!

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

什麼字符集服務器接收 後把它翻譯發表聲明?爲此,服務器使用character_set_connection 和collat​​ion_connection系統變量。它將由客戶端發送的 的語句從character_set_client轉換爲character_set_connection (除了具有介紹器的字符串文字(如_latin1或 _utf8))。 collat​​ion_connection對於文字字符串的比較非常重要。爲了與具有列值的字符串進行比較, collat​​ion_connection無關緊要,因爲列具有自己的 歸類,歸類優先級較高。