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

MySQL 遷移亂碼終極解決:latin1 庫實存 GBK 遷移至 utf8mb4 完整實戰

     編輯:MySQL 資料庫相關知識

核心誤區澄清

「任務是把 latin1 轉為 utf8」—— 錯!
真相:舊庫 (MySQL 4.x/5.0) 宣稱 latin1,實際存 GBK/GB2312 雙字節中文。MySQL 不驗證寫入內容是否符合聲稱字符集。

遷移正確邏輯:三步走「按 latin1 導出 → 告知 MySQL 實為 GBK → 導入轉 utf8mb4」

步驟 1:建立目標庫/表為 utf8mb4

CREATE DATABASE new_db CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
USE new_db;
-- 建表語句同樣指定 CHARSET=utf8mb4

步驟 2:以 latin1 導出 (不做任何轉換)

mysqldump -u root -p \
  --default-character-set=latin1 \   -- 關鍵:讀取時不轉碼
  --no-create-info \                 -- 僅導數據,結構單獨處理
  --skip-set-charset \               -- 避免產生 SET NAMES latin1 干擾導入
  old_db > data_latin1.sql

步驟 3:以 GBK 身份導入 (MySQL 內部完成 GBK → utf8mb4 轉碼)

mysql -u root -p \
  --default-character-set=gbk \      -- 關鍵:告知 MySQL 導入數據是 GBK
  new_db < data_latin1.sql

進階:含結構導出導入完整流程

# 1. 導出結構 (去除 CHARSET=latin1)
mysqldump -u root -p --no-data --skip-set-charset old_db |
  sed 's/CHARSET=latin1/CHARSET=utf8mb4/g' > struct_utf8mb4.sql

# 2. 建立目標庫並導入結構
mysql -u root -p -e "CREATE DATABASE new_db CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;"
mysql -u root -p new_db < struct_utf8mb4.sql

# 3. 導出數據 (純 latin1 二進位)
mysqldump -u root -p --default-character-set=latin1 --no-create-info --skip-set-charset old_db > data_latin1.sql

# 4. 導入數據 (按 GBK 解讀 → 存 utf8mb4)
mysql -u root -p --default-character-set=gbk new_db < data_latin1.sql

關鍵參數解析

參數作用為什麼需要
--default-character-set=latin1 (導出)讀取時不轉碼,保持原始位元組源表聲稱 latin1,實存 GBK,不轉碼才能保留原始 GBK 位元組
--skip-set-charset不在輸出中寫入 SET NAMES latin1避免導入時被此語句覆蓋 --default-character-set=gbk
--default-character-set=gbk (導入)告知 MySQL 客戶端發送的數據是 GBKMySQL 負責 GBK → utf8mb4 轉換並存儲
--set-charset=false (8.0+ 別名)同 --skip-set-charset同上

大文件處理 SET NAMES 行刪除技巧

# 假設 SET NAMES 在第 10 行,總 1987 行
head -9 dump.sql > clean.sql
tail -1977 dump.sql >> clean.sql
# 或用 sed 直接刪除
sed -i '/SET NAMES/d' dump.sql

驗證遷移結果

SELECT col, HEX(col), CHAR_LENGTH(col), LENGTH(col)
FROM new_db.target_table
WHERE col LIKE '%中文%';
-- HEX 應顯示 UTF-8 編碼 (如 E4B8ADE69687)
-- CHAR_LENGTH = 字符數, LENGTH = 字節數 (UTF-8 中文 3 字節)

總結

MySQL 遷移亂碼核心在於識別「聲稱字符集」與「實際存儲字符集」的不一致。latin1 導出 + GBK 導入 + utf8mb4 存儲 是經典 latin1→utf8 遷移的黃金法則。MySQL 8.0 預設 utf8mb4,新專案直接用 utf8mb4 避免此類坑。

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