中文亂碼核心在於「客戶端、連線、伺服器、資料庫、表、欄位」六層字符集不一致。本文以 DOS 環境實測,示範從連線參數、Session 變數、建庫建表到資料寫入的完整統一流程。
mysql --default-character-set=utf8 -u root -p
一次設定 character_set_client、connection、results 為 UTF-8。
SHOW VARIABLES LIKE 'character\_set\_%';
character_set_client utf8
character_set_connection utf8
character_set_database utf8
character_set_results utf8
character_set_server utf8
character_set_system utf8
SET character_set_results = gbk; -- DOS 視窗預設 GBK
SET character_set_client = gbk; -- 輸入編碼同步
-- 再次查詢變數,client/results 變為 gbk,其餘維持 utf8
原理:資料庫儲存 UTF-8,客戶端顯示需 GBK,連線層負責雙向轉碼。
CREATE DATABASE demo;
USE demo;
CREATE TABLE user (
id INT(11) NOT NULL AUTO_INCREMENT PRIMARY KEY,
name VARCHAR(100) NOT NULL,
age INT
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
INSERT INTO user (name, age) VALUES ('本職工作', 19);
INSERT INTO user (name, age) VALUES ('張工作', 22);
INSERT INTO user (age, name) VALUES (29, '王作');
SELECT * FROM user;
-- DOS 視窗正確顯示中文
[mysqld]
character-set-server = utf8mb4
collation-server = utf8mb4_unicode_ci
init_connect = 'SET NAMES utf8mb4'
[client]
default-character-set = utf8mb4
[mysql]
default-character-set = utf8mb4
SET NAMES。utf8mb4_unicode_ci 排序規則更準確,_general_ci 效能稍優。| 誤區 | 正確做法 |
|---|---|
| 只設定資料庫/表 CHARSET | 必須同步設定連線層 SET NAMES 或 --default-character-set |
| 用 latin1/swedish_ci 儲存中文 | 雙位元字元會被拆成兩個單位元,導致長度計算、排序、LIKE 全錯 |
| 應用層手動 iconv 轉碼 | 交給驅動程式/連線層自動處理,減少 Bug 面 |