**「寫入時的字元集 = 讀取時的字元集 = 儲存字元集」**
只要全鏈路一致,絕不亂碼。轉換發生在「客戶端字元集 ⇄ 資料庫字元集」之間,一致即免轉換、零損耗。
| 層級 | 系統變數 | 設定位置 | 建議值 |
|---|---|---|---|
| 1. 伺服器 | character_set_server | my.cnf [mysqld] | utf8mb4 |
| 2. 資料庫 | character_set_database | CREATE DATABASE ... CHARSET=utf8mb4 | utf8mb4 |
| 3. 資料表 | character_set_table (TABLE_COLLATION) | CREATE TABLE ... CHARSET=utf8mb4 | utf8mb4 |
| 4. 欄位 | character_set_column | col VARCHAR(100) CHARSET utf8mb4 | utf8mb4 |
| 5. 客戶端/連線 | character_set_client/connection/results | 連線參數 / SET NAMES | utf8mb4 |
[mysql]
default-character-set=utf8mb4
jdbc:mysql://host:3306/db?useUnicode=true&characterEncoding=utf8mb4&serverTimezone=UTC
$pdo = new PDO("mysql:host=localhost;dbname=test;charset=utf8mb4", $user, $pass);
$pdo->exec("SET NAMES utf8mb4");
conn = pymysql.connect(host='localhost', user='root', password='pass', db='test', charset='utf8mb4')
db, _ = sqlx.Open("mysql", "user:pass@tcp(host:3306)/db?charset=utf8mb4&parseTime=True&loc=Local")
-- 1. 檢視所有字元集變數
SHOW VARIABLES LIKE 'character_set_%';
SHOW VARIABLES LIKE 'collation_%';
-- 2. 檢視資料庫
SHOW CREATE DATABASE db_name;
-- 3. 檢視資料表
SHOW TABLE STATUS FROM db_name LIKE 'tbl_name';
SHOW CREATE TABLE tbl_name;
-- 4. 檢視欄位
SHOW FULL COLUMNS FROM tbl_name;
-- 5. 支援字元集列表
SHOW CHARSET;
utf8(MySQL 別名 utf8mb3):僅支援 BMP 平面(3 字節),不支援 Emoji、生僻漢字。utf8mb4:完整 UTF-8(4 字節),支援所有 Unicode 字符。**全面採用 utf8mb4**。-- 1. 資料庫
ALTER DATABASE db_name CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci;
-- 2. 所有表(需逐表執行)
ALTER TABLE tbl_name CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
-- CONVERT TO 會轉換資料,單純 CHARSET= 只改預設
-- 3. 修改連線配置
-- 4. 重啟應用驗證
utf8mb4_unicode_ci:標準 Unicode 排序,準確支援多語言(推薦)。utf8mb4_general_ci:舊版簡化排序,效能略高但不準確(如 ß=ss)。utf8mb4_bin:二進位比較,區分大小寫、口音,用於精確匹配/索引。| 現象 | 原因 | 修復 |
|---|---|---|
| 存入正常,讀出 ???/ | 讀取字元集錯誤(如 latin1 讀 utf8) | SET NAMES utf8mb4 / 修正連線參數 |
| 存入亂碼,讀出正常 | 寫入字元集錯誤 | 修正寫入端字元集,重寫資料 |
| Emoji 變 ?? | 使用 utf8 而非 utf8mb4 | 遷移至 utf8mb4 |
| 中文截斷/報錯 | 欄位長度按字元非位元組 | VARCHAR(100) 實際 300 位元組,擴大長度 |
建立「全鏈路 utf8mb4」標準,從架構層面根治亂碼顽疾。