2011-11-29 73 views
1

我在MySQL中遇到了編碼問題,我需要一些幫助來弄清楚發生了什麼。解密MySQL編碼

首先,一些參數。該表的默認編碼是utf8。然而,character_set_client,character_set_connection,collat​​ion_connection和character_set_server MySQL系統變量都是latin1。

我SSH入我的MySQL服務器,並使用本地命令行客戶端連接到本地服務器。我選擇記錄/列和返回的字符串,假設字符以A返回,這是正確的。 A在UTF-8中用十六進制表示爲「C5 9F」。

但是,命中服務器的PHP應用程序將其解釋爲XY。在MySQL命令行客戶端中,如果我發送命令「SET NAMES utf8」,它現在也將顯示爲XY。

如果我選擇INTO OUTFILE並使用hexedit編輯文件,我會看到兩個映射到X的十六進制字符,然後是映射到Y的兩個十六進制字符(X爲「c3 85」,「C5 B8」對於Y)。基本上,它採用兩個十六進制值並將它們確實顯示爲UTF8字符。

首先,它看起來像數據庫確實存儲的東西爲UTF8,但錯誤的UTF8種,正確嗎?它們是否以原始Unicode的形式進入,但不知何故,也許是因爲系統變量,它不會被轉換爲UTF8?

二,MySQL命令行客戶端如何/爲什麼將XY正確解釋爲A?

最後,爲了成功解釋MySQL命令行,是否有圖表顯示C3 85 C5 B8如何轉換爲A,或者XY轉換爲A?

非常感謝任何見解。

回答

2

你的問題是怎麼樣的混亂,所以我會用我自己的例子說明一下:

您連接到數據庫沒有發行SET NAMES,所以連接設置爲Latin-1的。這意味着數據庫預計您和它之間的任何通信都將以Latin-1進行編碼。
您將字節C3A2發送到數據庫,您希望在UTF-8編碼中使用「â」。
期待Latin-1的數據庫正在將其解釋爲字符「¢」(採用Latin-1編碼的C3A2)。
數據庫將在內部存儲這兩個字符,無論該表設置爲何種編碼。

以不同的方式連接到數據庫,運行SET NAMES UTF-8。數據庫現在期望以UTF-8與您交談。
您查詢存儲在數據庫中的數據,您收到以UTF-8編碼的字符「¢」作爲C382 C2A2,因爲您告訴數據庫存儲字符「¢」,並且您現在正在查詢它們UTF-8連接。

如果您再次使用Latin-1連接到數據庫以進行連接,數據庫將爲您提供以拉丁文-1編碼的字符「¢」,這些字符是字節C3 A2。如果您用來連接的客戶端正在使用Latin-1進行解釋,則會看到字符「¢」。如果客戶端正在將其解釋爲UTF-8,則會看到字符「â」。

從本質上講,這些都是某物可以搞砸了兩點:

  • 數據庫將解釋任何字節它接收爲字符在任何編碼設置爲連接和轉換的這些編碼字符以匹配它們應該存儲的表格
  • 數據庫將在檢索數據時將任何字符的編碼從其存儲的編碼轉換爲連接的編碼
  • 客戶端可以或可以不解釋字節它從數據庫接收到正確的字符,以顯示在屏幕上,尤其是命令行環境不是總是被設置爲正確顯示UTF-8數據

希望有所幫助。