字符集問題是 MySQL 中文應用最常見的坑。本文通過完整示例,涵蓋建庫建表、PHP 讀寫、舊數據遷移、客戶端選擇等全流程,助你徹底搞定編碼亂碼。
CREATE DATABASE IF NOT EXISTS my_db DEFAULT CHARSET utf8 COLLATE utf8_general_ci; CREATE TABLE my_table ( name VARCHAR(20) NOT NULL DEFAULT '' ) ENGINE=MyISAM DEFAULT CHARSET utf8;
COLLATE utf8_general_ci 指定排序校驗規則,庫級字符集會作為表的默認值。
mysql_connect('localhost','user','pass');
mysql_select_db('my_db');
mysql_query("SET NAMES utf8"); // 必須!設置連接層傳輸編碼
$name = mb_convert_encoding("測試", "utf-8", "gb2312"); // 本地編碼轉 UTF-8
mysql_query("INSERT INTO my_table VALUES('$name')");
header("Content-Type: text/html; charset=utf-8");
mysql_connect('localhost','user','pass');
mysql_select_db('my_db');
mysql_query("SET NAMES utf8");
$q = mysql_query("SELECT * FROM my_table");
while($r = mysql_fetch_row($q)) { print_r($r); }
若堅持使用 GB2312,建議表字符集設為 latin1(二進制存儲),配合 BINARY 屬性解決排序問題:
CREATE TABLE my_table ( name VARCHAR(20) BINARY NOT NULL DEFAULT '' ) ENGINE=MyISAM DEFAULT CHARSET latin1;
此法可在命令行直接操作中文,避免 gb2312/gbk 字符集在某些版本的兼容性問題。
mysqldump --default-character-set=latin1 -h localhost -u root -B my_db --tables old_table > old.sqliconv -t utf-8 -f gb2312 -c old.sql > new.sql(或省略 -f 自動檢測)new.sql 所有 INSERT/UPDATE 前插入 SET NAMES utf8;mysql -h localhost -u root my_db < new.sql完成後驗證數據完整性,大功告成!
SET NAMES UTF8; 即可。SET NAMES charset 是連接層編碼宣告,不可省略。mysqldump --default-character-set 正確聲明源編碼,再用 iconv 轉碼。