中文亂碼本質是「編碼不一致」:客戶端、連接層、服務端、存儲層任一環節編碼不匹配即導致數據損壞。本文提供標準化 UTF-8/utf8mb4 配置流程、參數詳解、驗證方法與版本差異說明。
mysql> status;
Server characterset: latin1
Db characterset: latin1
Client characterset: utf8
Conn. characterset: utf8
服務端/數據庫默認 latin1,客戶端用 utf8,寫入時發生 latin1 → utf8 錯誤轉換,讀取時反向轉換產生亂碼。
/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
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) |
[mysqld]
default-character-set = utf8 # 5.5 僅支持 utf8 (實為 utf8mb3)
# 5.5 若報錯改為 character_set_server = utf8
utf8mb4(支持 Emoji、生僻字)utf8 實為 utf8mb3,僅支持 BMP 平面字符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;
UPDATE t SET col = CONVERT(CAST(CONVERT(col USING latin1) AS BINARY) USING utf8mb4)(適用 latin1 存儲 utf8 字節)mysqldump --default-character-set=latin1 --set-charset=utf8mb4 導出後修改建表語句重導入pt-online-schema-change 在線修改表字符集(大表無鎖)?characterEncoding=utf8mb4&useSSL=false&serverTimezone=Asia/Shanghaicharset='utf8mb4' (PyMySQL) / charset='utf8mb4' (mysqlclient)mysqli_set_charset($link, 'utf8mb4') / PDO DSN charset=utf8mb4charset=utf8mb4 (go-sql-driver/mysql)<meta charset="utf-8">