經典錯誤現象
ERROR 1366 (HY000): Incorrect string value: '\xD5\xD4' for column 'name' at row 1
典型的「伺服器期望 UTF-8,客戶端送 GBK/Big5」編碼不匹配錯誤。
診斷第一步:檢視字符集變數
SHOW VARIABLES LIKE '%char%';
關鍵變數:
| 變數 | 含義 | 建議值 |
| character_set_server | 伺服器預設字符集 | utf8mb4 |
| character_set_database | 當前資料庫字符集 | utf8mb4 |
| character_set_client | 客戶端發送編碼 | 與客戶端實際編碼一致 |
| character_set_connection | 連線層轉換目標編碼 | utf8mb4 |
| character_set_results | 伺服器回傳編碼 | 與客戶端顯示編碼一致 |
解決方案分層
層級 1:資料庫/表/欄位定義(永久生效)
-- 一次性設定三大變數(推薦)
SET NAMES utf8mb4;
-- 等價於:
SET character_set_client = utf8mb4;
SET character_set_connection = utf8mb4;
SET character_set_results = utf8mb4;
-- 僅修改資料庫字符集(不影響連線編碼)
SET character_set_database = utf8mb4;
層級 3:客戶端/驅動程式配置(根本解決)
| 環境 | 配置方式 |
| MySQL 命令列 | mysql --default-character-set=utf8mb4 |
| my.cnf / my.ini | [client] default-character-set=utf8mb4 |
| PHP (mysqli) | $mysqli->set_charset('utf8mb4'); |
| PHP (PDO) | new PDO(..., array(PDO::MYSQL_ATTR_INIT_COMMAND => 'SET NAMES utf8mb4')); |
| Java (JDBC) | URL 加 ?characterEncoding=utf8mb4&useUnicode=true |
| Python (PyMySQL) | charset='utf8mb4' 參數 |
| Delphi (ZeosLib) | ZConnection1.Properties.Add('CodePage=utf8'); |
常見誤區
| 誤區 | 正確認知 |
| 只改 my.cnf 的 default-character-set | 僅影響伺服器啟動預設,不改變既有庫表、不控制連線編碼 |
| 用 utf8 而非 utf8mb4 | utf8 只支援 BMP 平面(3 字節),無法存 Emoji/生僻字,必須用 utf8mb4 |
| SET NAMES gbk 解決中文 | 治標不治本,資料實際以 GBK 存儲,跨系統交換會亂碼,統一用 utf8mb4 |
| 控制台插入正常、應用插入亂碼 | 控制台編碼與應用編碼不同,需分別配置客戶端編碼 |
驗證步驟
- 建立測試表:
CREATE TABLE t (c VARCHAR(20)) CHARSET=utf8mb4;
- 插入測試:
INSERT INTO t VALUES ('測試😀');
- 查詢驗證:
SELECT c, HEX(c), CHAR_LENGTH(c) FROM t;
- HEX 應顯示正確 UTF-8 編碼,CHAR_LENGTH 為字符數
總結:黃金法則
- **全鏈路統一 utf8mb4**
- 庫/表/欄位定義明確指定 CHARSET
- 客戶端/驅動程式連線參數設定字符集
- 避免依賴 SESSION 級 SET NAMES(易漏設)