MySQL 編碼問題是開發者最頭痛的「隱形殺手」。本文從 MySQL 4.1 版本架構變革切入,系統梳理伺服器層、資料庫層、表層、連線層、JDBC 驅動層五大配置節點,提供標準化配置模板與避坑清單,徹底解決亂碼根因。
MySQL 4.1 引入字符集與校對規則四層級繼承:
伺服器級 (character_set_server)
→ 資料庫級 (character_set_database)
→ 表級 (character_set_table)
→ 欄位級 (character_set_column)
連線層獨立:character_set_client / connection / results
[mysqld]
# 核心:預設字符集設為 utf8mb4(支援完整 Unicode,含 Emoji)
character-set-server = utf8mb4
collation-server = utf8mb4_unicode_ci
# 連線層預設(防止客戶端未顯式設定時亂碼)
character-set-client-handshake = FALSE # 強制忽略客戶端請求,使用伺服器設定
init_connect = 'SET NAMES utf8mb4' # 非超級用戶連線自動執行
# 其他建議
skip-character-set-client-handshake = 1 # 別名參數,兼容舊版
-- 資料庫
CREATE DATABASE mydb CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
-- 表(繼承資料庫,可覆蓋)
CREATE TABLE users (
id BIGINT PRIMARY KEY AUTO_INCREMENT,
name VARCHAR(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci,
bio TEXT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci
) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
-- 修改現有表(會重建表,大表慎用)
ALTER TABLE users CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
-- 連線後立即執行(所有語言通用)
SET NAMES utf8mb4;
-- 等價於:
SET character_set_client = utf8mb4;
SET character_set_connection = utf8mb4;
SET character_set_results = utf8mb4;
# MySQL Connector/J 5.1+ (支援 utf8mb4)
jdbc:mysql://localhost:3306/mydb?
useUnicode=true&
characterEncoding=utf8mb4&
autoReconnect=true&
failOverReadOnly=false&
serverTimezone=Asia/Taipei&
useSSL=false
# 連線池建議額外加上
&connectionInitSql=SET NAMES utf8mb4
版本關鍵點:
character_set_server,無需手動指定 characterEncodingcharacterEncoding=GBK/UTF-8utf8mb4,舊版 utf8 僅支援 BMP 平面(3 字節),Emoji 會截斷
# mysql 客戶端
mysql --default-character-set=utf8mb4 -u root -p
# 驗證當前連線編碼
SHOW VARIABLES LIKE 'character_set_%';
SHOW VARIABLES LIKE 'collation_%';
| 現象 | 根因 | 解決 |
|---|---|---|
| 中文存入顯示 ??? 或 亂碼 | 表/欄位字符集為 latin1,無法儲存中文 | ALTER TABLE ... CONVERT TO CHARACTER SET utf8mb4 |
| 讀取顯示亂碼,但十六進制正確 | 連線層 character_set_results 不匹配 | 應用層執行 SET NAMES utf8mb4 或 JDBC URL 加參數 |
| Emoji 存入變 ???? 或報錯 | 使用 utf8(3 字節)而非 utf8mb4(4 字節) | 全鏈路升級 utf8mb4:伺服器、資料庫、表、欄位、連線、JDBC |
| 工具顯示正常,應用亂碼 | 工具自動 SET NAMES,應用未設定 | 統一應用層連線初始化邏輯 |
| 備份/還原後亂碼 | mysqldump 無 --default-character-set |
mysqldump --default-character-set=utf8mb4 ... |
SHOW CREATE DATABASE db_name → 確認 CHARACTER SET = utf8mb4SHOW CREATE TABLE tbl_name → 確認表/欄位字符集SHOW VARIABLES LIKE 'character_set_%' → 連線三變數均為 utf8mb4mysqldump 導出 SQL 檔 → 用編輯器確認中文可讀黃金法則:全鏈路統一 utf8mb4,連線層顯式 SET NAMES,JDBC URL 帶參數,備份指定字符集。一次配置正確,終身免受亂碼之苦。