2007年8月18日 星期六

mysql 4.1/5.0 升級亂碼問題

緣由

升級mysql到4.1/5.0等支援unicode的版本後,馬上會遇到資料庫變亂碼的問題,主要的原因是早期的資料庫是採用 latin1 編碼去儲存 utf8, big5 等,到了 4.1 以後的版本開始支援unicode多國語系,所以從早期的升級上來會變成亂碼。


解決方法

先把有問題的資料庫用以下指令匯出
mysqldump -h 192.168.1.7 --default-character-set=latin1 tcse07 -p --compatible=mysql40 > tcse07.sql
以上指令的意思是要以 latin1 編碼的方式匯出資料庫 tcse07 的內容到 tcse07.sql 檔案,後面的 --compatible=mysql40 是為了使匯出的資料不包含 DEFAULT_CHARSET = latin1 的語系設定,這樣才可以確保匯出的資料是真正原始的資料,而非把 latin1 以 utf8 讀出來的資料

接下來要把轉過的資料在匯入資料庫中
這邊建議匯出以後,先把本來的資料庫 tcse07 刪除,重新建立使其使用 utf8 編碼,之後用以下指令把資料放回去
mysql -p --default-character-set=big5 tcse07
以上指令是要把目前要匯入資料庫 tcse07 的資料,以 big5 的方式讀取 tcse07.sql 並存入 tcse07 資料庫中

或是也可以在php連線的時候,指定以 latin1 的方式去讀去資料表的資料
mysql_connect("192.168.1.7", "root", "xxxx");
mysql_query("SET NAMES latin1");

總結

以上方法的大概就是要讓mysql在讀取以前舊的資料庫的時候,能夠以當時存進去的編碼方式讀出來
在 mysql 支援 Unicode 以前,其存資料的編碼都是 latin1,不管你實際上是用 big5 或 utf8,真正存到內部以後都是當作 latin1 處理
但是後期支援 Unicode 的版本,對於以前的資料會當作是 utf8 去把他讀出來,也就是會背景自動作 latin1 -> utf8 的動作,而不是 big5 -> utf8 的轉換,這也是導致亂碼的原因


其他

big5是以 2 bytes 的方式存檔,而 utf8 是 3 bytes,因此如果看到亂碼的時候,一個中文有2個亂碼,就是 big5,有三個就是 utf8
另外還有當以前php網頁存資料庫是big5的時候,如果不想把網頁改utf8,可以用以下方式解決資料庫讀出亂碼問題
mysql_connect("192.168.1.7", "root", "xxxx");
mysql_query("SET NAMES big5");
ps. SET NAMES的意思是要把資料庫中的資料轉成什麼編碼讀出來,例如存utf8,讀出成big5,但是必須在原本資料庫就是正確的情況下才有用

code:
/* 以Latin1讀取資料庫, 並於畫面顯示INSERT語法
* 使用時須加參數dump.php?table=aaaa
*/
$table=$_GET['table'];
mysql_connect("localhost", "user", "pass") or die(mysql_error());
mysql_select_db("loopek")or die(mysql_error());
mysql_query("SET NAMES 'latin1'");

$r=mysql_query("SELECT * FROM `$table`") or die(mysql_error());

while( $d=mysql_fetch_assoc($r) ) {
$a="INSERT INTO `$table` VALUES (";
foreach($d as $data)
$a = $a."'$data', ";
$a=substr($a, 0, strlen($a)-2);
echo "$a);<br>";
}

沒有留言:

Related Posts Plugin for WordPress, Blogger...