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

MySQL 中文亂碼終極解決:全鏈路字符集一致性指南 (utf8mb4 版)

     編輯:MySQL 綜合教學

亂碼本質:字符集不匹配導致的編碼/解碼錯誤

MySQL 預設 latin1 (ISO-8859-1 西歐字符集),不支援中文。插入中文時,編碼與存儲字符集不一致,產生 ??? 或亂碼。

全鏈路一致性鐵律

客戶端編碼 = 連接字符集 = 表字符集 = 列字符集 = 結果集字符集 = 應用輸出編碼

**任何一環斷裂 → 亂碼**

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

1. 服務器配置 (my.cnf)

[mysqld]
character-set-server = utf8mb4
collation-server = utf8mb4_unicode_ci
init_connect = 'SET NAMES utf8mb4'  -- 自動設置連接字符集
skip-character-set-client-handshake  -- 強制忽略客戶端請求字符集

[client]
default-character-set = utf8mb4

[mysql]
default-character-set = utf8mb4

2. 建庫建表顯式指定 (雙重保險)

CREATE DATABASE `my_db` 
  DEFAULT CHARACTER SET utf8mb4 
  COLLATE utf8mb4_unicode_ci;

CREATE TABLE `users` (
  `id` INT AUTO_INCREMENT PRIMARY KEY,
  `name` VARCHAR(50) NOT NULL,
  `content` TEXT
) ENGINE=InnoDB 
  DEFAULT CHARSET=utf8mb4 
  COLLATE=utf8mb4_unicode_ci;

3. 連接字串指定字符集 (各語言)

語言/驅動連接字串 / 代碼
JDBCjdbc:mysql://host:3306/db?useUnicode=true&characterEncoding=utf8mb4&zeroDateTimeBehavior=convertToNull
PHP PDOnew PDO("mysql:host=host;dbname=db;charset=utf8mb4", $user, $pass)
PHP mysqli$mysqli->set_charset('utf8mb4')
Python PyMySQLcharset='utf8mb4' 參數
Go sqlxparseTime=true&charset=utf8mb4
Node.js mysql2charset: 'utf8mb4'
命令行客戶端mysql --default-character-set=utf8mb4 -u user -p

4. 應用輸出編碼

// Web 頁面

// HTTP 響應頭
Content-Type: text/html; charset=UTF-8
// JSON API
Content-Type: application/json; charset=UTF-8

⚠️ 關鍵避坑:utf8 vs utf8mb4

特性utf8 (MySQL 別名 utf8mb3)utf8mb4
最大字節3 字節4 字節
支援 Emoji❌✅
支援生僻字❌ (部分)✅ (Unicode 全集)
索引長度限制767 字節 (InnoDB)767 字節 (需 innodb_large_prefix=ON 解除 3072)

結論:全鏈路統一用 utf8mb4,拒絕 utf8

存量系統遷移指南

# 1. 修改配置文件 my.cnf (如上)
# 2. 重啟 MySQL
# 3. 轉換庫/表/欄位
ALTER DATABASE `db` CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci;
ALTER TABLE `table` CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
-- 或單欄位
ALTER TABLE `table` MODIFY `col` VARCHAR(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;

# 4. 驗證
SELECT CHARSET(column_name), COLLATION(column_name) FROM information_schema.COLUMNS WHERE TABLE_SCHEMA='db';

臨時緊急方案 (不重啟、不改表結構)

// PHP 連接後立即執行
$pdo->exec("SET NAMES 'utf8mb4'");
// 或 mysqli
$mysqli->query("SET NAMES 'utf8mb4'");
// 或舊版 mysql
mysql_query("SET NAMES 'utf8mb4'", $conn);

原理:SET NAMES 相當於同時設置 character_set_client、character_set_connection、character_set_results 三個會話變量。

JSP/Servlet 環境特殊配置

// 1. 頁面指令
<%@ page contentType="text/html;charset=UTF-8" pageEncoding="UTF-8" %>

// 2. Filter 統一設置 (web.xml)

  EncodingFilter
  com.example.EncodingFilter
  
    encoding
    UTF-8
  


  EncodingFilter
  /*


// 3. Tomcat server.xml Connector

驗證清單

  1. 插入測試:INSERT INTO t VALUES ('中文😀')
  2. 查看原始字節:SELECT HEX(col), CHAR_LENGTH(col), CHARSET(col) FROM t
  3. 應用端讀取顯示正常
  4. binlog 內容正常:mysqlbinlog -v binlog.000001 | grep 中文
  5. 備份恢復驗證:mysqldump → 恢復 → 查詢正常

中文亂碼不是 MySQL 的錯,是 **全鏈路字符集不一致** 的錯。**統一 utf8mb4、顯式指定、驗證閉環**,一次配置,永久告別亂碼。

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