MySQL的中文UTF8亂碼問(wèn)題
從MySQL支持Unicode后,為了與時(shí)俱進(jìn),我們的web程序也開(kāi)始考慮用UTF8了。其實(shí)UTF8也用了好幾年了,程序基本能跑,沒(méi)什么大問(wèn)題,但是數(shù)據(jù)倒換的時(shí)候,總是遇到不爽的事情。
【問(wèn)題現(xiàn)象】
網(wǎng)頁(yè)xxx.php用EditPlus另存為UTF8格式,MySQL在my.ini里設(shè)置default-character-set=utf8,建表時(shí)加了CREATE TABLE `xxx ` (myname varchar(255)) ENGINE=MyISAM DEFAULT CHARSET=utf8,用xxx.php執(zhí)行insert/update/select出來(lái)的都是中文,貌似沒(méi)問(wèn)題,但是用phpMyAdmin看select是亂碼,用第三方工具軟件(如SQLyog)看select也是亂碼,mysqldump也是亂碼,很不爽。當(dāng)然,如果你建表的時(shí)候,選擇了binary/varbinary/blob類(lèi)型,不會(huì)發(fā)現(xiàn)亂碼,因?yàn)橹付ǖ氖嵌M(jìn)制保存,MySQL保存數(shù)據(jù)時(shí)就沒(méi)有編碼的概念了。
【查找問(wèn)題】
雖然在my.ini里設(shè)置default-character-set=utf8,但是執(zhí)行以下命令時(shí)有新發(fā)現(xiàn):
|
mysql> SHOW VARIABLES LIKE 'character%'; +----------------------------------------+------------------------- | Variable_name | Value +----------------------------------------+------------------------- | character_set_client | latin1 | character_set_connection | latin1 | character_set_database | utf8 | character_set_filesystem | binary | character_set_results | latin1 | character_set_server | utf8 | character_set_system | utf8 | character_sets_dir | D:\mysql\share\charsets\ +----------------------------------------+------------------------- 8 rows in set (0.00 sec)
mysql> SHOW VARIABLES LIKE 'collation_%'; +---------------------------------------+------------------ | Variable_name | Value +---------------------------------------+------------------ | collation_connection | latin1_swedish_ci | collation_database | utf8_general_ci | collation_server | utf8_general_ci +--------------------------------------+------------------ 3 rows in set (0.00 sec) |
發(fā)現(xiàn)Value列里面不全是utf8,仍然有部分是latin1,比如其中的client和connection。那網(wǎng)頁(yè)xxx.php的工作過(guò)程就是這樣的啦:從xxx.php頁(yè)面上輸入漢字,因?yàn)閤xx.php是UTF8編碼的,所以xxx.php以UTF8格式轉(zhuǎn)換輸入的漢字,然后以UTF8提交給mysql,但是mysql的client和connection都是latin1的,而表是UTF8的,所以mysql存儲(chǔ)時(shí),先將xxx.php提交的漢字,轉(zhuǎn)成latin1的格式,再轉(zhuǎn)成UTF8字符格式存在表中。如果此時(shí)我們用第三方軟件或者phpMyAdmin去select查看此表,而表中存儲(chǔ)的數(shù)據(jù)是被latin1過(guò)的UTF8字符,出來(lái)的時(shí)候是以UTF8格式取的,當(dāng)然看起來(lái)時(shí)亂碼了。解決方法就是讓所有過(guò)程都是UTF8的就可以了。
【解決問(wèn)題】
1、從my.ini下手
|
[client] default-character-set=utf8 [mysql] default-character-set=utf8 [mysqld] default-character-set=utf8 |
以上3個(gè)section都要加default-character-set=utf8,平時(shí)我們可能只加了mysqld一項(xiàng)。
然后重啟mysql,執(zhí)行
mysql> SHOW VARIABLES LIKE 'character%';
mysql> SHOW VARIABLES LIKE 'collation_%';
確保所有的Value項(xiàng)都是utf8即可。
2、建表時(shí)加utf8,表字段的Collation可加可不加,不加時(shí)默認(rèn)是utf8_general_ci了。
|
CREATE TABLE `tablename4` ( `id` int(11) NOT NULL AUTO_INCREMENT, `varchar1` varchar(255) DEFAULT NULL, `varbinary1` varbinary(255) DEFAULT NULL, PRIMARY KEY (`id`) ) ENGINE=MyISAM DEFAULT CHARSET=utf8 |
3、網(wǎng)頁(yè)xxx.php保存時(shí)選擇utf8編碼,頁(yè)頭最好加上
header('conten-type:text/html;charset=utf-8');
在執(zhí)行CRUD操作前先執(zhí)行一下
mysql_query("set names utf8");
測(cè)試代碼xxx.php如下:
|
<?php header('conten-type:text/html;charset=utf-8'); mysql_connect("localhost", "root", "password") or die("Could not connect: " . mysql_error()); mysql_select_db("test"); mysql_query("set names utf8"); $str = "CHN 軟件開(kāi)發(fā)有限公司,JPN ソフトウェア開(kāi)発株式會(huì)社,KOR 소프트웨어 개발 유한 공사,RUS Суд программного обеспечения".time(); $sql = "insert into tablename4 (varchar1, varbinary1 ) values ('".$str."','".$str."')"; echo $sql."<hr>"; mysql_query($sql);
$result = mysql_query("SELECT id, varchar1 ,varbinary1 FROM tablename4"); while ($row = mysql_fetch_array($result, MYSQL_BOTH)) { printf ("ID: %s , varchar1: %s, varbinary1: %s<br>", $row[0], $row["varchar1"], $row["varbinary1"]); }
mysql_free_result($result); ?> |
如此設(shè)置之后,無(wú)論是在php頁(yè)面插入任何utf8字符,在php頁(yè)面里取出來(lái)的,在phpMyAdmin里取出來(lái)的,在mysql的第三方客戶(hù)端軟件里取出來(lái)的,都是一樣的漢字了,不會(huì)再發(fā)現(xiàn)亂碼,mysqldump出來(lái)的也是漢字。OK,問(wèn)題解決。
【另】在中文windows系統(tǒng)下,在cmd.exe里運(yùn)行mysql.exe字符終端,不能使用上面的規(guī)則,因?yàn)槟J(rèn)情況下,中文windows系統(tǒng)cmd.exe里的代碼頁(yè)是cp936即GBK,不能顯示全部UTF8字符,所以在字符終端里看到亂碼是正?,F(xiàn)象,不要奇怪,這個(gè)問(wèn)題在類(lèi)Unix系統(tǒng)的shell終端里可以解決的。
相關(guān)文章
使用mysqldump對(duì)MySQL的數(shù)據(jù)進(jìn)行備份的操作教程
這篇文章主要介紹了使用mysqldump對(duì)MySQL的數(shù)據(jù)進(jìn)行備份的操作教程,示例環(huán)境基于CentOS操作系統(tǒng),需要的朋友可以參考下2015-12-12
Mysql Limit 分頁(yè)查詢(xún)優(yōu)化詳解
這篇文章主要介紹了Mysql Limit 分頁(yè)查詢(xún)優(yōu)化的相關(guān)資料,非常不錯(cuò),介紹的非常詳細(xì),具有參考借鑒價(jià)值,需要的朋友可以參考下2016-09-09
SQL中count(1)、count(*)?與?count(列名)的區(qū)別詳細(xì)解釋
count(1)和count(*)是SQL中用于統(tǒng)計(jì)行數(shù)的兩種常見(jiàn)方式,它們的區(qū)別在于統(tǒng)計(jì)的對(duì)象不同,下面這篇文章主要給大家介紹了關(guān)于SQL中count(1)、count(*)?與?count(列名)區(qū)別的相關(guān)資料,需要的朋友可以參考下2024-08-08
MySQL Workbench導(dǎo)出表結(jié)構(gòu)與數(shù)據(jù)的實(shí)現(xiàn)步驟
MySQL Workbench是一個(gè)強(qiáng)大的數(shù)據(jù)庫(kù)設(shè)計(jì)工具,提供了便捷的數(shù)據(jù)導(dǎo)入導(dǎo)出功能,本文就來(lái)介紹一下MySQL Workbench導(dǎo)出表結(jié)構(gòu)與數(shù)據(jù)的實(shí)現(xiàn)步驟,感興趣的可以了解一下2024-05-05

