本質:**編碼鏈路斷層**。客戶端編碼 → 連接層編碼 → 服務端內部編碼 → 表/欄位編碼 → 存儲編碼,任一環節不一致即導致亂碼。
[client]
default-character-set = utf8mb4
[mysqld]
character-set-server = utf8mb4
collation-server = utf8mb4_general_ci
skip-character-set-client-handshake # 強制忽略客戶端指定編碼
systemctl restart mysqld
CREATE DATABASE `mydb`
DEFAULT CHARACTER SET utf8mb4
COLLATE utf8mb4_general_ci;
-- ❌ 錯誤:預設 latin1
CREATE TABLE `mydb` (
`username` VARCHAR(64) NOT NULL,
`userid` INT(11) NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
-- ✅ 正確:顯式 utf8mb4
CREATE TABLE `mydb` (
`username` VARCHAR(64) NOT NULL,
`userid` INT(11) NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci;
-- 1. 服務端變量
SHOW VARIABLES LIKE 'character_set_%';
SHOW VARIABLES LIKE 'collation_%';
-- 期望:character_set_server/client/connection/results/database = utf8mb4
-- 2. 庫級
SELECT DEFAULT_CHARACTER_SET_NAME, DEFAULT_COLLATION_NAME
FROM information_schema.SCHEMATA WHERE SCHEMA_NAME = 'mydb';
-- 3. 表級
SHOW CREATE TABLE `mydb`.`mydb`; -- 看 DEFAULT CHARSET
-- 4. 欄位級
SHOW FULL COLUMNS FROM `mydb`.`mydb`; -- 看 Collation
-- 5. 實測寫讀
INSERT INTO `mydb` (`username`, `userid`) VALUES ('測試中文😀', 1);
SELECT HEX(`username`), `username` FROM `mydb`; -- HEX 應為 E6B58BE8AF95E4B8ADE69687F09F9880
?characterEncoding=utf8mb4&useSSL=falsecharset='utf8mb4'mysql:host=...;dbname=...;charset=utf8mb4user:pass@tcp(host:3306)/db?charset=utf8mb4,utf8utf8 僅支援 BMP (3字節),Emoji/生僻字需 utf8mb4 (4字節)。SET NAMES utf8mb4 僅對當前連接生效。UPDATE t SET c = CONVERT(CAST(CONVERT(c USING latin1) AS BINARY) USING utf8mb4);本文方案適用 MySQL 5.5.24+ 至 8.0+。5.5 以前版本參數名稱不同 (default-character-set 在 [mysqld]),強烈建議升級至受支援版本。