首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫

MySQL 插入中文變 ??? 完整排查與修復清單

     編輯:MySQL 資料庫相關知識

現象:插入「測試」 → 存入「???」或「」

本質:**編碼鏈路斷層**。客戶端編碼 → 連接層編碼 → 服務端內部編碼 → 表/欄位編碼 → 存儲編碼,任一環節不一致即導致亂碼。

三步修復鐵三角

1. 配置文件:服務端與客戶端默認編碼

[client]
default-character-set = utf8mb4

[mysqld]
character-set-server = utf8mb4
collation-server = utf8mb4_general_ci
skip-character-set-client-handshake  # 強制忽略客戶端指定編碼
systemctl restart mysqld

2. 建庫:指定默認字符集

CREATE DATABASE `mydb` 
DEFAULT CHARACTER SET utf8mb4 
COLLATE utf8mb4_general_ci;

3. 建表:顯式聲明欄位/表字符集

-- ❌ 錯誤:預設 latin1
CREATE TABLE `mydb` (
  `username` VARCHAR(64) NOT NULL,
  `userid` INT(11) NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=latin1;

-- ✅ 正確:顯式 utf8mb4
CREATE TABLE `mydb` (
  `username` VARCHAR(64) NOT NULL,
  `userid` INT(11) NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci;

驗證清單 (逐項確認)

-- 1. 服務端變量
SHOW VARIABLES LIKE 'character_set_%';
SHOW VARIABLES LIKE 'collation_%';
-- 期望:character_set_server/client/connection/results/database = utf8mb4

-- 2. 庫級
SELECT DEFAULT_CHARACTER_SET_NAME, DEFAULT_COLLATION_NAME 
FROM information_schema.SCHEMATA WHERE SCHEMA_NAME = 'mydb';

-- 3. 表級
SHOW CREATE TABLE `mydb`.`mydb`;  -- 看 DEFAULT CHARSET

-- 4. 欄位級
SHOW FULL COLUMNS FROM `mydb`.`mydb`;  -- 看 Collation

-- 5. 實測寫讀
INSERT INTO `mydb` (`username`, `userid`) VALUES ('測試中文😀', 1);
SELECT HEX(`username`), `username` FROM `mydb`;  -- HEX 應為 E6B58BE8AF95E4B8ADE69687F09F9880

應用層連接配置 (同樣關鍵)

  • JDBC 8.0+:無需額外參數,驅動自動協商 utf8mb4。
  • JDBC 5.x:?characterEncoding=utf8mb4&useSSL=false
  • Python PyMySQL:charset='utf8mb4'
  • PHP PDO:mysql:host=...;dbname=...;charset=utf8mb4
  • Go:user:pass@tcp(host:3306)/db?charset=utf8mb4,utf8

避坑指南

  1. utf8 ≠ utf8mb4:MySQL 的 utf8 僅支援 BMP (3字節),Emoji/生僻字需 utf8mb4 (4字節)。
  2. 只改表不改庫/配置:新表繼承庫默認,庫繼承服務端默認,鏈路任一環 latin1 即亂碼。
  3. 應用層連接字符串缺 charset:驅動預設常為 latin1,導致「庫表全對,寫入卻亂碼」。
  4. 修改配置未重啟:動態修改 SET NAMES utf8mb4 僅對當前連接生效。
  5. 歷史 latin1 資料修復:UPDATE t SET c = CONVERT(CAST(CONVERT(c USING latin1) AS BINARY) USING utf8mb4);

版本說明

本文方案適用 MySQL 5.5.24+ 至 8.0+。5.5 以前版本參數名稱不同 (default-character-set 在 [mysqld]),強烈建議升級至受支援版本。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved