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

MySQL 字符集配置全解析:從變量原理到 latin1→utf8mb4 遷移實戰

     編輯:MySQL 資料庫相關知識

字符集不一致是「亂碼」「數據截斷」「索引失效」的元兇。本文系統講解 MySQL 字符集變量傳遞鏈路、客戶端-轉換器-服務端三層轉換模型、動態修改與持久化配置、存量數據庫 latin1 遷移至 utf8mb4 的四步導出導入法,附生產環境巡檢清單。

一、 字符集核心變量與傳遞鏈路

SHOW VARIABLES LIKE 'character%';
+--------------------------+----------------------------+
| Variable_name            | Value                      |
+--------------------------+----------------------------+
| character_set_client     | latin1   <-- 客戶端聲明     |
| character_set_connection | latin1   <-- 轉換器目標     |
| character_set_database   | latin1   <-- 庫默認         |
| character_set_filesystem | binary   <-- 文件系統       |
| character_set_results    | latin1   <-- 結果集編碼     |
| character_set_server     | latin1   <-- 服務端默認     |
| character_set_system     | utf8     <-- 元數據固定     |
| character_sets_dir       | /usr/share/mysql/charsets/ |
+--------------------------+----------------------------+

三層轉換模型

客戶端 (gbk) → 字符集轉換器 (client→connection) → 服務端 (utf8)
                ↑                    ↑
           character_set_client  character_set_connection
                ↑                    ↑
           character_set_results ← character_set_server
  • 客戶端通過 SET NAMES 或驅動屬性聲明 character_set_client。
  • 轉換器將請求從 client 轉為 connection,再按 server 存儲。
  • 結果集按 character_set_results 編碼返回給客戶端。

二、 亂碼與數據丟失成因

現象根因對策
亂碼client 與實際編碼不符(如 Windows cmd 默認 gbk 卻設 utf8)客戶端正確聲明編碼
亂碼results 與客戶端顯示編碼不符統一 results = client
數據截斷/丟失connection 字符集容量 < client(如 client=utf8, connection=latin1)connection ≥ client,建議均為 utf8mb4

三、 動態修改與持久化

-- 會話級(當前連接生效)
SET NAMES utf8mb4;  -- 等價於 client/connection/results 三者同設

-- 全局級(需配合配置文件持久化)
SET GLOBAL character_set_server = utf8mb4;
SET GLOBAL character_set_database = utf8mb4;
# my.cnf 永久生效
[client]
default-character-set = utf8mb4

[mysql]
default-character-set = utf8mb4

[mysqld]
character-set-client-handshake = FALSE
character-set-server = utf8mb4
collation-server = utf8mb4_unicode_ci
init_connect = 'SET NAMES utf8mb4'

四、 存量 latin1 庫遷移至 utf8mb4 四步法

1. 導出表結構(指定 latin1 連接,保持中文可見)

mysqldump -uroot -p --default-character-set=latin1 -d DB_NAME > createtable.sql
# -d 僅導結構

2. 修改 createtable.sql:將 CHARSET=latin1 批量替換為 CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci

3. 導出數據(latin1 連接,--quick 避免大內存)

mysqldump -uroot -p --default-character-set=latin1 \
  --quick --no-create-info --extended-insert DB_NAME > data.sql

4. 修改 data.sql:SET NAMES latin1 → SET NAMES utf8mb4

5. 重建庫表並導入

CREATE DATABASE DB_NAME DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
mysql -uroot -p DB_NAME < createtable.sql
mysql -uroot -p DB_NAME < data.sql

五、 生產環境巡檢清單

  1. SHOW VARIABLES LIKE 'character_set%':client/connection/database/results/server 全為 utf8mb4。
  2. SELECT TABLE_SCHEMA, TABLE_NAME, TABLE_COLLATION FROM information_schema.TABLES WHERE TABLE_SCHEMA NOT IN ('mysql','sys','performance_schema','information_schema') AND TABLE_COLLATION NOT LIKE 'utf8mb4%':零行通過。
  3. SELECT TABLE_SCHEMA, TABLE_NAME, COLUMN_NAME, COLLATION_NAME FROM information_schema.COLUMNS WHERE TABLE_SCHEMA NOT IN (...) AND COLLATION_NAME NOT LIKE 'utf8mb4%':零行通過。
  4. 應用端 JDBC/ODBC/PHP/Go 驅動連接參數顯式指定 charset=utf8mb4。
  5. 新建表默認 CHARSET=utf8mb4,CI/CD 流水線集成 pt-table-checksum 校驗主從字符集一致性。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved