MySQL 字符集體系涉及服務器、庫、表、列、連接五個層次,配置不當是亂碼的主因。本文系統整理查看命令、修改方法、轉換流程、最佳實踐與避坑指南。
utf8mb4_general_ci,_ci=大小寫不敏感)_utf8mb4 '字符串' 指定字面量編碼,避免轉換損耗| 層次 | 系統變量 | 作用 | 查看命令 |
|---|---|---|---|
| 服務器 | character_set_server | 默認內部操作字符集 | SHOW VARIABLES LIKE 'character_set_%';SHOW VARIABLES LIKE 'collation_%'; |
| 庫 | character_set_database | 當前庫默認字符集 | |
| 表/列 | (定義時指定) | 表/列級字符集 | |
| 客戶端 | character_set_client | 客戶端發送數據編碼 | |
| 連接 | character_set_connection | 連接層轉換目標編碼 | |
| 結果 | character_set_results | 查詢結果返回編碼 | |
| 系統 | character_set_system | 元數據 (列名等) 編碼,固定 utf8 |
SHOW VARIABLES LIKE 'character%';
SHOW VARIABLES LIKE 'collation%';
-- 輸出示例 (已優化配置)
+--------------------------+----------------------------+
| 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_sets_dir | /usr/share/mysql/charsets/ |
+--------------------------+----------------------------+
[mysqld]
character-set-server = utf8mb4
collation-server = utf8mb4_general_ci
init_connect = 'SET NAMES utf8mb4 COLLATE utf8mb4_general_ci'
[client]
default-character-set = utf8mb4
[mysql]
default-character-set = utf8mb4
重啟 MySQL 生效:systemctl restart mysqld
SET NAMES utf8mb4; -- 等價於下面三句
SET character_set_client = utf8mb4;
SET character_set_results = utf8mb4;
SET character_set_connection = utf8mb4;
-- 單獨設置
SET character_set_database = utf8mb4;
SET collation_connection = utf8mb4_general_ci;
CREATE DATABASE mydb DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;
CREATE TABLE t (c VARCHAR(100)) CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci;
ALTER TABLE t MODIFY c VARCHAR(100) CHARACTER SET utf8mb4;
character_set_client → character_set_connectioncharacter_set_server
character_set_results
| 場景 | 斷點 | 現象 |
|---|---|---|
| 插入 utf8 數據,連接為 latin1 | 步驟 1 | utf8→latin1 轉換,非 latin1 字符變 ? |
| 庫表為 latin1,連接為 utf8 | 步驟 2 | utf8→latin1 存儲,超出範圍變 ? |
| 查詢 utf8 數據,結果集為 latin1 | 步驟 3 | 雙重編碼,顯示亂碼 |
-- 查看實際存儲字節
SELECT HEX(col), CHAR_LENGTH(col), LENGTH(col) FROM t;
-- 查看列字符集與校對
SELECT CHARSET(col), COLLATION(col) FROM t LIMIT 1;
-- 列出所有字符集/校對
SHOW CHARACTER SET;
SHOW COLLATION;
<meta charset="utf-8">CHARSET=utf8mb4,不依賴默認值SET NAMES utf8mb4,重連亦同mysql_options(mysql, MYSQL_SET_CHARSET_NAME, "utf8mb4")WHERE col = _utf8mb4 '值' 使用引入器mysqldump --default-character-set=utf8mb4| 誤區 | 真相 |
|---|---|
| my.cnf 改了就生效 | 僅影響 mysql 客戶端工具,不影響 libmysqlclient/應用連接 |
| utf8 支援所有字符 | MySQL utf8 = utf8mb3,**不支援 Emoji**,需 utf8mb4 |
| SET NAMES 一次永久 | 僅當前會話,斷開重連失效 |
| 修改庫字符集會轉換現有表 | 只影響新建表,存量表需 CONVERT TO CHARACTER SET |
MySQL 字符集配置的核心是五層統一。採用 utf8mb4 + 顯式指定 + 連接初始化 SET NAMES 模式,配合 HEX()/CHARSET() 診斷工具,可構建零亂碼的數據庫環境。新項目直接上 utf8mb4,舊項目按「二進制中轉」遷移。