首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 數據庫知識 >  >> MySQL 資料庫 >> MySQL 綜合教學

MySQL 中文亂碼徹底解決:字符集配置、連接參數與表級修正全攻略

     編輯:MySQL 綜合教學

前言

中文亂碼是 MySQL 開發者的「成人禮」。根因在於 **Client → Connection → Server → Database → Table → Column** 六層字符集不一致。MySQL 預設 latin1,不支援中文。本文從配置檔、連接參數、建表語句、資料修正四個層面,給出徹底解決方案。

字符集傳遞鏈路


Client (應用/終端) 
  → character_set_client
Connection (JDBC/ODBC/CLI)
  → character_set_connection
Server (mysqld)
  → character_set_server / character_set_database
Database
  → DEFAULT CHARACTER SET
Table
  → DEFAULT CHARACTER SET
Column
  → CHARACTER SET

**核心原則**:六層**全部統一為 utf8mb4**(支援 Emoji、完整 Unicode),而非舊版 utf8(僅 3 字節,缺補充平面字符)。

方案一:配置檔全域設定(my.cnf / my.ini)


[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'
skip-character-set-client-handshake  # 強制忽略客戶端請求的字符集

修改後 **重啟 mysqld** 生效。適用於全新部署或可控制所有客戶端的環境。

方案二:連接參數指定(JDBC / Python / Go / PHP)

不依賴 Server 配置,由應用層強制指定,最穩健。

JDBC (MySQL Connector/J 5.1+ / 8.0+)


# 5.1 版本
jdbc:mysql://host:3306/db?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&serverTimezone=Asia/Shanghai

# 8.0+ 版本(自動識別 utf8mb4)
jdbc:mysql://host:3306/db?characterEncoding=utf8mb4&serverTimezone=Asia/Shanghai

Python (PyMySQL / mysqlclient)


conn = pymysql.connect(host='...', user='...', password='...', db='...', charset='utf8mb4')
# 或
conn = MySQLdb.connect(..., charset='utf8mb4')

Go (go-sql-driver/mysql)


dsn := "user:pass@tcp(host:3306)/db?charset=utf8mb4&parseTime=True&loc=Local"

PHP (PDO / mysqli)


// PDO
$pdo = new PDO("mysql:host=...;dbname=...;charset=utf8mb4", $user, $pass);
// mysqli
$mysqli->set_charset("utf8mb4");

方案三:建表/建庫時顯式指定


-- 資料庫層級
CREATE DATABASE mydb DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;

-- 表層級
CREATE TABLE t_user (
  id BIGINT PRIMARY KEY AUTO_INCREMENT,
  name VARCHAR(50) NOT NULL COMMENT '姓名',
  bio TEXT COMMENT '簡介'
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci;

-- 欄位層級(覆蓋表預設)
ALTER TABLE t_user MODIFY COLUMN bio TEXT CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;

方案四:存量資料修正(已出現亂碼)

  1. 確認當前編碼:SHOW CREATE TABLE t_user、SELECT HEX(col) FROM t_user LIMIT 1 分析位元組。
  2. 若資料實為 UTF-8 但標記為 latin1(常見雙重編碼):
    
    ALTER TABLE t_user 
      CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;
    

    CONVERT TO 會**轉換資料位元組**,而 DEFAULT CHARSET 僅改元資料。

  3. 若資料已損壞(亂碼入庫):需從備份恢復或人工修正,無法自動修復。

驗證檢查清單


-- 1. 連線層面
SHOW VARIABLES LIKE 'character_set_%';
-- 期望:client/connection/results/database/server 皆為 utf8mb4

-- 2. 表/欄位層面
SHOW CREATE TABLE t_user;
-- 期望:DEFAULT CHARSET=utf8mb4,欄位無額外 CHARSET 或同為 utf8mb4

-- 3. 實際寫讀測試
INSERT INTO t_user (name) VALUES ('測試😀');
SELECT name, HEX(name) FROM t_user WHERE id=LAST_INSERT_ID();
-- HEX 應為 E6B58BE8AF95F09F9880 (UTF-8MB4)

常見誤區

誤區正確認知
用 utf8 而非 utf8mb4utf8 = utf8mb3,不支援 Emoji、生僻字,必須用 utf8mb4
只改 my.cnf 不重啟需重啟 mysqld 才生效
只改表 DEFAULT CHARSET不轉換既有資料,必須用 CONVERT TO
JDBC 用 characterEncoding=utf8驅動會映射為 utf8mb3,建議 utf8mb4 或依賴 8.0+ 自動協商

總結

**「全鏈路 utf8mb4」** 是解決中文亂碼的唯一正解。新專案:my.cnf + 連接參數 + 建表語句三重保險。存量專案:CONVERT TO CHARACTER SET utf8mb4 一鍵轉換(備份先行)。將字符集治理納入上線檢查清單,杜絕亂碼根源。

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