萬盛學電腦網

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

徹底解決 MySQL 中文亂碼:字符集編碼配置全攻略(含 5.5/5.6/5.7/8.0 差異)

中文亂碼本質是「編碼不一致」:客戶端、連接層、服務端、存儲層任一環節編碼不匹配即導致數據損壞。本文提供標準化 UTF-8/utf8mb4 配置流程、參數詳解、驗證方法與版本差異說明。

問題現象與根因

mysql> status;
Server characterset: latin1
Db characterset: latin1
Client characterset: utf8
Conn. characterset: utf8

服務端/數據庫默認 latin1,客戶端用 utf8,寫入時發生 latin1 → utf8 錯誤轉換,讀取時反向轉換產生亂碼。

標準化配置流程(推薦 utf8mb4)

1. 修改配置文件 /etc/my.cnf

[client]
default-character-set = utf8mb4

[mysql]
default-character-set = utf8mb4

[mysqld]
character-set-server = utf8mb4
collation-server = utf8mb4_unicode_ci
init_connect = 'SET NAMES utf8mb4'  # 連接初始化

# 可選:禁用字符集自動轉換(需應用層保證編碼一致)
# skip-character-set-client-handshake

2. 重啟服務並驗證

service mysqld restart

mysql> status;
Server characterset: utf8mb4
Db characterset: utf8mb4
Client characterset: utf8mb4
Conn. characterset: utf8mb4

mysql> SHOW VARIABLES LIKE 'character_set_%';
+--------------------------+---------+
| Variable_name            | Value   |
+--------------------------+---------+
| character_set_client     | utf8mb4 |
| character_set_connection | utf8mb4 |
| character_set_database   | utf8mb4 |
| character_set_filesystem | binary  |
| character_set_results    | utf8mb4 |
| character_set_server     | utf8mb4 |
| character_set_system     | utf8    |
+--------------------------+---------+

參數詳解

參數作用
character_set_client客戶端發送請求的編碼
character_set_connection連接層接收後內部處理編碼
character_set_database當前默認數據庫編碼(無默認庫時同 server)
character_set_filesystem文件系統路徑編碼(通常 binary)
character_set_results結果集返回給客戶端的編碼
character_set_server服務器級默認編碼
character_set_system系統元數據編碼(固定 utf8)

版本差異注意事項

MySQL 5.5 及之前

[mysqld]
default-character-set = utf8  # 5.5 僅支持 utf8 (實為 utf8mb3)
# 5.5 若報錯改為 character_set_server = utf8

MySQL 5.6 / 5.7

  • 推薦 utf8mb4(支持 Emoji、生僻字)
  • utf8 實為 utf8mb3,僅支持 BMP 平面字符

MySQL 8.0+

  • 默認字符集已改為 utf8mb4,校對規則 utf8mb4_0900_ai_ci
  • 無需額外配置即可完美支持中文

建庫建表最佳實踐

-- 建庫顯式指定
CREATE DATABASE IF NOT EXISTS mydata 
  DEFAULT CHARACTER SET utf8mb4 
  COLLATE utf8mb4_unicode_ci;

-- 建表顯式指定(覆蓋庫級默認)
CREATE TABLE users (
  id BIGINT PRIMARY KEY AUTO_INCREMENT,
  name VARCHAR(50) NOT NULL COMMENT '用戶名'
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;

已有亂碼數據修復策略

  1. 雙重轉換法:UPDATE t SET col = CONVERT(CAST(CONVERT(col USING latin1) AS BINARY) USING utf8mb4)(適用 latin1 存儲 utf8 字節)
  2. 導出重導:mysqldump --default-character-set=latin1 --set-charset=utf8mb4 導出後修改建表語句重導入
  3. 工具修復:pt-online-schema-change 在線修改表字符集(大表無鎖)

應用層檢查清單

  • JDBC URL:?characterEncoding=utf8mb4&useSSL=false&serverTimezone=Asia/Shanghai
  • Python:charset='utf8mb4' (PyMySQL) / charset='utf8mb4' (mysqlclient)
  • PHP:mysqli_set_charset($link, 'utf8mb4') / PDO DSN charset=utf8mb4
  • Go:charset=utf8mb4 (go-sql-driver/mysql)
  • 前端頁面:<meta charset="utf-8">
copyright © 萬盛學電腦網 all rights reserved