MySQL 字元集問題的本質是「資料寫入時的位元組序列」與「讀取時的解碼方式」不匹配。本文從實戰經驗出發,闡述編碼一致性原則、PHPMyAdmin 匯入陷阱、跨編碼轉換實作。
若四者一致,完全不需要 在 MySQL 層面做任何轉換,資料原樣存儲、原樣讀取。
CHARSET=gbk。SET NAMES gbk (或 PDO charset=gbk)。CHARSET=utf8 (或 utf8mb4)。SET NAMES utf8。應用層必須轉碼:
// PHP 範例:寫入時 GBK→UTF-8 儲存
$utf8_str = iconv('GBK', 'UTF-8', $gbk_str);
mysqli_query($link, "SET NAMES utf8");
mysqli_query($link, "INSERT INTO t(c) VALUES ('$utf8_str')");
// 讀取時 UTF-8→GBK 顯示
mysqli_query($link, "SET NAMES utf8");
$res = mysqli_query($link, "SELECT c FROM t");
$row = mysqli_fetch_assoc($res);
echo iconv('UTF-8', 'GBK', $row['c']);
或使用 mb_convert_encoding()。
iconv -f gbk -t utf-8 轉碼 SQL 檔,再用 PHPMyAdmin 匯入。SET NAMES gbk 後執行 SQL。iconv('UTF-8','GBK',...) 反向修正 (治標不治本)。| 變數 | 含義 |
|---|---|
| character_set_client | Client 送出陳述式的編碼 |
| character_set_connection | Server 將陳述式轉為此編碼處理 |
| character_set_results | Server 回傳結果集的編碼 |
| character_set_database/table/column | 各層級預設字元集 |
| SET NAMES 'charset' | 等同同時設定 client/connection/results 三者 |
字元集問題 90% 來自「連線字元集與資料實際編碼不符」。新專案強制統一 UTF-8 (utf8mb4):檔案、資料庫、連線、HTML 標頭、HTTP Header 全鏈路 UTF-8,即可徹底杜絕亂碼。舊專案遷移請參照「MySQL 4.1 字元集升級遷移指南」。