MySQL 4.1+ 引入多層字符集轉換機制,理解 character_set_client、character_set_connection、character_set_results 三大參數流向,是徹底解決亂碼的鑰匙。
客戶端發送 SQL (client charset)
↓ 轉換
服務器解析執行 (connection charset)
↓ 轉換 (若表/列 charset 不同)
存儲引擎寫入 (column charset)
↓ 讀取時轉換
結果集返回 (results charset)
| 參數 | 含義 | 典型設置 | 影響階段 |
|---|---|---|---|
character_set_client | 客戶端發送 SQL 字節流的編碼 | utf8mb4 / binary (不轉換) | SQL 發送 → 服務器接收 |
character_set_connection | 服務器內部解析、執行 SQL 使用的編碼 | utf8mb4 | SQL 解析、比較、臨時表 |
character_set_results | 結果集返回給客戶端前的目標編碼 | utf8mb4 / NULL (不轉換) | 結果集發送 → 客戶端接收 |
@mysql_query("SET character_set_connection=$dbcharset,
character_set_results=$dbcharset,
character_set_client=binary", $link);
client=binary:告訴服務器「我發送的是二進制字節流,請直接按 connection 指定編碼解釋」,避免雙重轉換。connection=results=$dbcharset:統一內部處理與輸出編碼,消除中間環節轉換損耗與錯誤。| 現象 | 根因 | 修正 |
|---|---|---|
| 插入中文變 ??? / 亂碼 | client/connection 不匹配,或表列 charset 錯誤 | 統一設置 SET NAMES utf8mb4;表列 ALTER CHARSET utf8mb4 |
| 查詢顯示亂碼 | results 編碼與頁面/終端編碼不一致 | SET character_set_results=utf8mb4;HTTP Header/HTML meta 聲明 UTF-8 |
| WHERE 中文條件匹配失效 | connection 編碼導致比較語義改變 | 確保 connection=client=數據編碼 |
-- 等價於同時設置 client/connection/results
SET NAMES utf8mb4 COLLATE utf8mb4_unicode_ci;
-- 或分別顯式設置(精細控制)
SET character_set_client = utf8mb4;
SET character_set_connection = utf8mb4;
SET character_set_results = utf8mb4;
new PDO("mysql:host=...;dbname=...;charset=utf8mb4", ...)$mysqli->set_charset("utf8mb4")jdbc:mysql://...?characterEncoding=utf8mb4&connectionCollation=utf8mb4_unicode_cicharset='utf8mb4'「源頭統一、傳輸透明、落地一致」—— 客戶端、連接層、服務器、表列、結果集、應用頁面**全鏈路 utf8mb4**,亂碼自然消失。