萬盛學電腦網

您现在的位置: 萬盛學電腦網 >> 程式設計 >  >> 資料庫 >> MySQL 教學

MySQL Warning 1366 Incorrect string value 解決:字符集編碼不匹配根因與修復

錯誤現象

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

解決方案(按推薦度)

方案一:全鏈路 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 顯示正確編碼字節。

最佳實踐清單

  1. 新項目強制 utf8mb4
  2. 舊項目遷移:CONVERT TO CHARACTER SET + 連接層 SET NAMES
  3. 應用框架配置字符集(Laravel database.php、Spring connectionInitSqls 等)
  4. 啟用 STRICT_TRANS_TABLES 讓編碼錯誤報錯而非靜默截斷
copyright © 萬盛學電腦網 all rights reserved
字符集覆蓋範圍最大字節MySQL 別名
GB2312簡體中文 6763 字2gb2312
GBKGB2312 + 繁體 + 日文假名 + 擴展區2gbk
UTF8MB3BMP 平面 Unicode3utf8
UTF8MB4全 Unicode (含 Emoji)4utf8mb4