錯誤現象
Warning (Code 1366): Incorrect string value: '\xC2\xCC\xB9\xE2\xC9\xAD...' for column 'msg' at row 1
插入包含中文(如「綠光森林」)的日志時,字段內容被截斷,僅存入中文前的 ASCII 部分。
根因分析
字符集編碼範圍不匹配:
- 表/字段/連接字符集為
GB2312(僅覆蓋簡體中文 6763 字)
- 數據含繁體字/生僻字/日文假名,超出 GB2312 範圍
- MySQL 無法編碼 → 截斷存儲 → 報警告
GB2312 vs GBK vs UTF8MB4
| 字符集 | 覆蓋範圍 | 最大字節 | MySQL 別名 |
| GB2312 | 簡體中文 6763 字 | 2 | gb2312 |
| GBK | GB2312 + 繁體 + 日文假名 + 擴展區 | 2 | gbk |
| UTF8MB3 | BMP 平面 Unicode | 3 | utf8 |
| UTF8MB4 | 全 Unicode (含 Emoji) | 4 | utf8mb4 |
解決方案(按推薦度)
方案一:全鏈路 UTF8MB4(根治,推薦)
-- 1. 數據庫/表/字段
CREATE DATABASE db CHARSET utf8mb4 COLLATE utf8mb4_general_ci;
ALTER TABLE t CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;
-- 2. 連接層 (每次連接執行)
SET NAMES utf8mb4;
-- 或 PDO: $pdo->exec("SET NAMES utf8mb4");
-- 或 mysqli: $mysqli->set_charset('utf8mb4');
-- 3. 配置文件 my.cnf
[client]
default-character-set = utf8mb4
[mysql]
default-character-set = utf8mb4
[mysqld]
character-set-server = utf8mb4
collation-server = utf8mb4_general_ci
init_connect = 'SET NAMES utf8mb4'
方案二:升級至 GBK(兼容舊項目)
ALTER TABLE t CONVERT TO CHARACTER SET gbk COLLATE gbk_chinese_ci;
SET NAMES gbk;
可解決繁體/日文假名問題,但不支持 Emoji、生僻字,非長久之計。
方案三:臨時屏蔽警告(不推薦)
SET sql_mode = ''; -- 移除 STRICT_TRANS_TABLES 等嚴格模式
會導致數據靜默截斷,極不推薦生產環境使用。
驗證修復
INSERT INTO logs(msg) VALUES('綠光森林DVD13.rmvb');
SELECT msg, HEX(msg), CHAR_LENGTH(msg) FROM logs WHERE msg LIKE '%綠光%';
正常應完整存儲,HEX 顯示正確編碼字節。
最佳實踐清單
- 新項目強制 utf8mb4
- 舊項目遷移:
CONVERT TO CHARACTER SET + 連接層 SET NAMES
- 應用框架配置字符集(Laravel
database.php、Spring connectionInitSqls 等)
- 啟用
STRICT_TRANS_TABLES 讓編碼錯誤報錯而非靜默截斷
copyright ©
萬盛學電腦網 all rights reserved