mysql的字符集
character_set_client , character_set_connection , character_set_results
中文亂碼
[@more@]關於MYSQL的字符集,系統裡面有很多個變數設定,很多初學者都不太搞得清楚,包括我自己也是.
所以在這裡寫點東西,希望把這幾個東西的關係搞清楚.
MYSQL的字符集變數可以透過以下命令得到:
show variables like 'char%';
+--------------------------+----------------------------+
| Variable_name | Value |
+--------------------------+----------------------------+
| character_set_client | gbk |
| character_set_connection | gbk |
| character_set_database | utf8 |
| character_set_filesystem | binary |
| character_set_results | |
| character_set_server | utf8 |
| character_set_system | utf8 |
| character_sets_dir | /usr/share/mysql/charsets/ |
+--------------------------+----------------------------+
MYSQL的字符集變數其實可以分為兩類,
一類是關於建立OBJECTS時要用到的.
一類是關於建立OBJECTS時要用到的.
character_set_database
character_set_server
character_set_server
一類是在伺服器處理連線的時候要用到的.
character_set_client
character_set_connection
character_set_results
character_set_client
character_set_connection
character_set_results
我們主要關注的是處理連線的字符集.
關注字符集問題,那你肯定是遇到了亂碼的問題. 其實解決亂碼問題在網上一搜一大堆.
如果能做到, 應用/MYSQL.CLENT/MYSQL.CONNETION/表/MYSQL.RESULT 的字符集一致,存取資料肯定沒有問題.
我在這裡把這三個連線字符集的關係理理.
經過多次的測試,我把MYSQL處理字元的過程主要歸納為:
例: WINDOWS客戶端CHARSET=GBK,輸入"中" , 透過WINDOWS.GBK轉碼為 $a = D6D0,
========================================================================================
# 伺服器收到CLIENT送來的值"D6D0", 並認為"D6D0"是$MYSQL.character_set_client 指定字符集的資料.
# 從 $MYSQL.character_set_client 轉化---> $MYSQL.character_set_connection (如果字符集一樣就不轉換)
if 轉換成功 ; then
$a = $MYSQL.character_set_client.code
else
$a = 3f (在這個環節不會報錯!)
fi
# 從 $MYSQL.character_set_connection 轉化---> $TABLES.character_set (如果字符集一樣也會檢查一次)
if 轉換成功 ; then
$a = $MYSQL.character_set_client.code , 並存入表
else
$a = 3f , 並報錯: Incorrect string value
$a = 20 ($MYSQL.character_set_connection = $TABLES.character_set 的情況)
fi
# 從資料庫取資料.
# 從 $TABLES.character_set --> $MYSQL.character_set_result
if 轉換成功 ; then
$a = $MYSQL.character_set_result.code , 正常顯示
else
$a = 3f/亂碼 , 顯示: ?或者亂碼
fi========================================================================================
========================================================================================
# 伺服器收到CLIENT送來的值"D6D0", 並認為"D6D0"是$MYSQL.character_set_client 指定字符集的資料.
# 從 $MYSQL.character_set_client 轉化---> $MYSQL.character_set_connection (如果字符集一樣就不轉換)
if 轉換成功 ; then
$a = $MYSQL.character_set_client.code
else
$a = 3f (在這個環節不會報錯!)
fi
# 從 $MYSQL.character_set_connection 轉化---> $TABLES.character_set (如果字符集一樣也會檢查一次)
if 轉換成功 ; then
$a = $MYSQL.character_set_client.code , 並存入表
else
$a = 3f , 並報錯: Incorrect string value
$a = 20 ($MYSQL.character_set_connection = $TABLES.character_set 的情況)
fi
# 從資料庫取資料.
# 從 $TABLES.character_set --> $MYSQL.character_set_result
if 轉換成功 ; then
$a = $MYSQL.character_set_result.code , 正常顯示
else
$a = 3f/亂碼 , 顯示: ?或者亂碼
fi========================================================================================
以下是我測試過程中記錄的各種情況及報錯資訊,以便大家分析:
(在這裡我特意用了SSHTERM的兩種字符集進行測試. 我們可以把它理解為應用.)
SSHTERM | CHAR_client | CHAR_connection | tutf_dump | tgbk_dump | tlatin1_dump | tutf_warning | tgbk_warning | tlatin1_warning |
gbk | utf8 | utf8 | 20 | 3f | 3f | Incorrect 'xD6xD0' 存入表UTF8轉UTF8,這個環節字符集一樣也轉換一次.但在源字符集中沒找到.返回"空" | Incorrect 'xD6xD0' 存入表,用UTF8轉GBK時報錯 | Incorrect 'xD6xD0' 存入表,用UTF8轉LATIN1時報錯 |
gbk | gbk | e4b8ad | d6d0 | 3f | 正常 | 正常 | Incorrect 'xD6xD0' 存入表時用GBK轉LATIN1時報錯 | |
D6D0 | latin1 | latin1 | c396c390 | 3f3f | d6d0 | 正常:(存了UTF8的D6D0) 如果以LATIN1取還是"D6D0" | Incorrect 'xD6xD0' LATIN1轉GBK報錯 | 正常 |
gbk | utf8 | e4b8ad | d6d0 | 3f | 正常 | 正常 | Incorrect xE4xB8xAD 存入表,用UTF8轉LATIN1時報錯 | |
utf8 | gbk | 3f | 3f | 3f | CLIENT向CONN轉換時已經丟了資料成3F,這中間的轉換不會報錯 | |||
utf8 | gbk | gbk | e6b693 | e4b8 | 3f | Data truncated "E4B8AD"只取了_GBK "E4B8" | Incorrect 'xAD "E4B8AD"被兩分了兩段,而AD沒能轉換成功. | Incorrect 'xE4xB8xAD' |
在CONN向錶轉換的時候,上面兩個的處理結果為什麼不一樣呢? | ||||||||
utf8 | utf8 | e4b8ad | d6d0 | 3f | 正常 | 正常 | Incorrect xE4xB8xAD | |
E4B8AD | gbk | utf8 | e6b693 | e4b8 | 3f | CLENT轉CONN資料被擷取, 但這樣的處理不會報錯. | CLENT轉CONN資料被擷取, 但這樣的處理不會報錯. | Incorrect 'xE6xB6x93' |
utf8 | gbk | e4b8ad | d6d0 | 3f | 正常 | 正常 | Incorrect 'xD6xD0' | |
latin1 | latin1 | c3a4c2b8c2ad | 3f3f3f | e4b8ad | 理論上這是"E4B8AD"UTF8的CODE,但又有點不像 | xE4xB8xAD LATIN1向GBK轉不成功 | 正常 |
上表中,只要DUMP結果為e4b8ad/d6d0,說明資料儲存都是正常的.而且可以正常讀取.
DUMP結果為c396c390的情況比較特殊.讀者稍加分析應該還是能明白的.(其實就是原存原取).
相關命令:
========= ========= ========= ========= ========= ========= ========= =========
建立測試表:
create table tutf (name char(10)) engine=myisam default character set=utf8 ;
create table tgbk (name char(10)) engine=myisam default character set=gbk ;
create table tlat (name char(10)) engine=myisam default character set=latin1 ;
設定相關字符集:
set character_set_client=gbk ;
set character_set_connection=utf8;
set character_set_results=latin1;
插入並DUMP資料:
truncate table tutf;truncate table tgbk;truncate table tlat;
insert into tutf values ('中'); show warnings ;
insert into tgbk values ('中'); show warnings ;
insert into tlat values ('中'); show warnings ;
system hexdump /home/mysql/data/test/tutf.MYD ;
system hexdump /home/mysql/data/test/tgbk.MYD ;
system hexdump /home/mysql/data/test/tlat.MYD ;
========= ========= ========= ========= ========= ========= ========= =========
set character_set_client=gbk ;
set character_set_connection=utf8;
set character_set_results=latin1;
插入並DUMP資料:
truncate table tutf;truncate table tgbk;truncate table tlat;
insert into tutf values ('中'); show warnings ;
insert into tgbk values ('中'); show warnings ;
insert into tlat values ('中'); show warnings ;
system hexdump /home/mysql/data/test/tutf.MYD ;
system hexdump /home/mysql/data/test/tgbk.MYD ;
system hexdump /home/mysql/data/test/tlat.MYD ;
========= ========= ========= ========= ========= ========= ========= =========
相關資料:
============================
中文: 中
GBK編碼 : D6D0
UTF8編碼: E4B8AD
============================
============================
中文: 中
GBK編碼 : D6D0
UTF8編碼: E4B8AD
============================
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/703656/viewspace-1028279/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- MySQL字符集MySql
- (6)mysql 中的字符集MySql
- 【Mysql 學習】mysql 字符集MySql
- 修改MySQL字符集MySql
- mysql 字符集修改MySql
- MySQL修改字符集MySql
- 聊一聊MySQL的字符集MySql
- mysql伺服器的字符集MySql伺服器
- Ubuntu下修改mysql的字符集UbuntuMySql
- mysql字符集說明MySql
- 設定Mysql字符集MySql
- mysql字符集設定MySql
- mysql字符集小結MySql
- mysql 字符集造成的效能問題MySql
- mysql的字符集校對規則MySql
- 修改mysql預設字符集的方法MySql
- MySQL 4.1 字符集支援的原理(轉)MySql
- mysql字符集和字元排序MySql字元排序
- MySQL DB字符集修改方法MySql
- mysql 字符集亂碼探究MySql
- Mysql字符集與字元序MySql字元
- mysql字符集與亂碼MySql
- 小談MySQL字符集(轉)MySql
- MySQL檢視和修改字符集的方法MySql
- mysql修改表、欄位、庫的字符集MySql
- 請教mysql中字符集的問題MySql
- MySQL 不同版本預設字符集MySql
- mysql 資料型別,字符集MySQL 資料型別
- Mysql 字符集引數翻譯MySql
- 【Mysql】iconv 轉換字符集MySql
- mysql關於字符集character set的總結MySql
- 【Mysql】字符集引發的主從報錯MySql
- [MySQLFAQ]系列–如何更改MySQL的預設字符集MySql
- 淺談MySQL備份字符集的問題MySql
- mysql亂碼?一勞永逸修改mysql字符集!MySql
- MySQL 5.7 版本的 UTF8 字符集調研MySql
- MYSQL 字符集不同引起的join無法走索引MySql索引
- mysql亂碼現象及對字符集的理解MySql