MySQL字符集問題

2021-07-05 03:03:02 字數 1997 閱讀 7517

遇到了這麼個問題,資料庫表的字符集是utf8,但客戶端程式在建立連線時設定了:set names latin1。

查詢資料庫中的中文字元「尊」的列,返回的是」尚「。

「尊」和「尚」被錯誤的認為是相等的。

要解釋上邊的怪現象需要先明確以下幾個概念:

需要知道這三個函式

這幾個概念網上的資料很多,在這裡就不廢話了。

需要特別說明下,character_set_client是客戶端傳輸資料到伺服器端使用的字符集。

character_set_connection是伺服器端在處理文字時預設使用的字符集。這個character_set_connection因為名字用了connection,比較容易產生誤解,我一開始就誤解成了客戶端和伺服器端建立連線使用的字符集。

假設set names utf8,此時character_set_connection的值將被設定為utf8.

執行 select『尊』;

相當於 select (_utf8 『尊』)

(在這裡我們使用乙個比較特殊的符號「_utf8」,它叫做「引介詞」,可參考資料)

單獨的乙個select並不能說明問題,我們對字串進行一下比較,執行以下sql:

select * from test where name=』尊』

假設列test.name的字符集是utf8,此時字串』尊』的字符集也是utf8,將直接進行比較,不需要進行字符集轉換。

此時的sql相當於:

select * from test where name = (_utf8 『尊』)

如果set names gbk後再次執行以上sql,此時test.name的字符集仍然是utf8,但『尊』的字符集變成了gbk,等價sql如下:

select * from test where name = (_gbk 『尊』)

在進行字串比較時會進行隱式的字符集轉換。

關於字符集比較和隱式轉換可參考資料(mysql manual - collation of expressions

理解了以上幾個概念,我們解釋下文章開頭的怪現象。

由於設定了set names latin1,字元從客戶端傳到伺服器端使用的是latin1字符集

由於資料庫表中的字符集是utf8,在進行比較的時候會再次將latin1的字元隱式轉換成utf8。

以上比較繞的整個過程可以簡化為如下一條sql:

select convert(_latin1』尊』 using utf8)

(將』尊』先轉化為latin1編碼,再轉換為utf8編碼)

前期存到資料庫的漢字「尚」也是這樣乙個轉換過程,使用如下sql檢驗:

select convert(_latin1』尊』 using utf8) = convert(_latin1』尚』 using utf8);

返回結果為相等。

以上實驗只是重現了相等的過程,並沒有解釋為什麼會相等。

這牽扯latin1編碼的問題。latin1是單位元組編碼,不認識漢字,但將漢字轉換成latin1編碼的時候將保留原來的編碼格式直接儲存。如漢字「尊」和「尚」的編碼為:

select hex(『尊』) => e5b08a

select hex(『尚』) => e5b09a

這兩個漢字被編碼為3個位元組,這三個位元組在latin1字符集裡對應的字母是:å°š和å°š

這兩個字串å°š和å°š在utf8的預設比較規則下相等。

檢視』尊』被轉換後成為的十六進製制:

select hex(convert(_latin1』尊』 using utf8)) => c3a5c2b0c5a0

檢視』尊』被轉換後對應的字元:

select unhex(hex(convert(_latin1』尊』 using utf8))) => å°š

ok,解釋完畢。

總結如下:

不能瞎用latin1連線去查詢或操作utf8編碼的資料庫資料。

mysql字符集問題 mysql字符集問題

我們新建mysql資料庫的時候,需要指定資料庫的字符集,一般我們都是選擇utf8這個字符集,但是還會又乙個utf8mb4這個字符集,好像和utf8有聯絡,今天就來解析一下這兩者的區別。起源mysql在5.5.3之後增加了這個utf8mb4的編碼,mb4就是most bytes 4的意思,專門用來相容...

mysql字符集問題 mysql字符集問題

用show variables like char 檢視mysql的引數,結果應如下 mysql show variables like char variable name value character set client gbk character set connection gbk ch...

mysql字符集問題 MySql字符集問題

mysql字符集問題 xinjinlong 2010 11 14 22 10 47 閱讀 1334 上次說了一下c從mysql裡面讀取資料,這次在介紹一下如何把mysql的字符集設定為utf8 第一 檢視自己mysql的字符集 mysql show variables like character ...