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

MySQL 字符集編碼深度理解:從 latin1 到 utf8mb4 的演進與避坑指南

     編輯:MySQL 綜合教學

字符集與校對規則核心概念

  • 字符集:字元到位元組的映射規則(如 utf8mb4、gbk、latin1)
  • 校對規則:字元比較/排序規則(如 utf8mb4_unicode_ci、utf8mb4_general_ci、utf8mb4_bin)
  • ci/cs/bin:ci=不區分大小寫、cs=區分大小寫、bin=二進制比較

MySQL 關鍵字符集層級

utf8 vs utf8mb4:核心差異

層級系統變數作用範圍典型設定
伺服器character_set_server預設資料庫/表/欄位utf8mb4
資料庫character_set_database該資料庫新建表預設utf8mb4
資料表TABLE CHARSET該表新建欄位預設utf8mb4
欄位COLUMN CHARSET實際儲存編碼utf8mb4
連線character_set_client/connection/results客戶端↔伺服器傳輸編碼utf8mb4
結果集character_set_results伺服器→客戶端編碼utf8mb4
特性utf8 (utf8mb3)utf8mb4
最大位元組/字元3 bytes4 bytes
支援 Unicode 範圍基本多文種平面 (BMP, U+0000-U+FFFF)完整 Unicode (含輔助平面 Emoji、生僻字)
MySQL 版本5.5.3 前預設5.5.3+ 可用,8.0 預設
索引長度限制767 bytes (InnoDB)767 bytes (需 innodb_large_prefix=ON 解除 3072 bytes)
結論:全面棄用 utf8,統一使用 utf8mb4。MySQL 8.0 已將 utf8 別名指向 utf8mb3(即將移除)。

校對規則選擇指南

  • utf8mb4_unicode_ci:依 Unicode 標準排序(準確支援多語言)、效能略低 → 推薦預設
  • utf8mb4_general_ci:舊版簡化排序(較快但不準,如 ß=s、œ=oe) → 相容舊系統用
  • utf8mb4_0900_ai_ci:MySQL 8.0 新預設,支援 Unicode 9.0、語言無關、效能優化 → 8.0 首選
  • utf8mb4_bin:二進制比較,區分大小寫/重音,適合精確匹配(如密碼雜湊)

連線字符集「三件套」設定

客戶端連線時需三者一致,否則發生隱性轉碼導致亂碼:

SET NAMES utf8mb4 COLLATE utf8mb4_unicode_ci;
-- 等同於
SET character_set_client = utf8mb4;
SET character_set_connection = utf8mb4;
SET character_set_results = utf8mb4;

各語言/框架設定方式

環境設定方式
PHP PDO$dsn = "mysql:host=...;charset=utf8mb4";
PHP mysqli$mysqli->set_charset("utf8mb4");
Java JDBCurl?characterEncoding=utf8mb4&connectionCollation=utf8mb4_unicode_ci
Python PyMySQLcharset='utf8mb4'
Go sqlxdsn "charset=utf8mb4,utf8" (驅動自動協商)
MySQL 客戶端mysql --default-character-set=utf8mb4 或 [client] default-character-set=utf8mb4

常見亂碼場景與根因

現象根因解決
中文變 ??? 或 亂碼連線字符集非 utf8mb4(如 latin1),寫入時截斷/錯誤映射SET NAMES utf8mb4 / 修正連線配置
Emoji 存成 ????表/欄位字符集為 utf8 (3 bytes),無法儲存 4 bytes 字元ALTER TABLE ... CONVERT TO CHARSET utf8mb4
查詢結果正常,應用顯示亂碼應用讀取時未指定 charset,預設 latin1/系統編碼解碼應用層指定 utf8mb4 解碼
ORDER BY 排序異常校對規則不支援該語言(如 general_ci 對中文拼音排序無效)改用 unicode_ci 或指定語言校對

遷移現有資料庫至 utf8mb4 完整步驟

  1. 備份:mysqldump --single-transaction --routines --triggers -u root -p db > backup.sql
  2. 修改配置:my.cnf 設定 character_set_server=utf8mb4、collation_server=utf8mb4_unicode_ci
  3. 轉換資料庫:ALTER DATABASE db CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci;
  4. 轉換每張表:ALTER TABLE tbl CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
  5. 檢查欄位長度:VARCHAR(255) 在 utf8mb4 佔 1020 bytes,可能超過索引限制 → 改 VARCHAR(191) 或開啟 innodb_large_prefix=ON + innodb_file_format=Barracuda + ROW_FORMAT=DYNAMIC
  6. 驗證:插入 Emoji 測試、檢查 SHOW CREATE TABLE、應用端全鏈路測試

總結

MySQL 字符集核心原則:全鏈路 utf8mb4 + unicode_ci/0900_ai_ci。伺服器、資料庫、表、欄位、連線、應用層六個層級全部對齊,才能徹底杜絕亂碼。MySQL 8.0 已將此設為預設,舊版升級務必執行完整遷移流程。

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