utf8 (實為 utf8mb3) 僅支持 BMP 平面,**最多 3 字節/字符**,無法存儲 Emoji (😀 U+1F600)、生僻漢字 (𠮷 U+20BB7)、特殊符號等 4 字節字符。ERROR 1366 (HY000): Incorrect string value: '\xF0\x9F\x98\x80' for column 'col'。-- 庫級 ALTER DATABASE db_name CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci; -- 表級 (含數據轉換,大表必須用 pt-osc/gh-ost) ALTER TABLE tbl_name CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci; -- 僅修改表默認字符集 (不轉換現有列數據,慎用) ALTER TABLE tbl_name CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci; -- 列級檢查 (確認無殘留 utf8 列) SELECT TABLE_SCHEMA, TABLE_NAME, COLUMN_NAME, CHARACTER_SET_NAME, COLLATION_NAME FROM information_schema.COLUMNS WHERE TABLE_SCHEMA = 'db_name' AND CHARACTER_SET_NAME != 'utf8mb4';
-- 1. 會話級驗證
SHOW VARIABLES LIKE '%character%';
-- 關鍵項均為 utf8mb4
-- 2. 實測插入 Emoji
CREATE TABLE emoji_test (c VARCHAR(10) CHARACTER SET utf8mb4) ENGINE=InnoDB;
INSERT INTO emoji_test VALUES ('😀'), ('🎉'), ('🚀'), ('💯');
SELECT c, HEX(c), CHAR_LENGTH(c), LENGTH(c) FROM emoji_test;
-- HEX: F09F9880 (4 字節), CHAR_LENGTH=1, LENGTH=4
-- 3. 應用端插入驗證 (Java)
String sql = "INSERT INTO emoji_test VALUES (?)";
try (PreparedStatement ps = conn.prepareStatement(sql)) {
ps.setString(1, "😎👍");
ps.executeUpdate();
}
| 現象 | 原因 | 解決 |
|---|---|---|
| 客戶端工具下拉菜單無 utf8mb4 選項 | 工具版本過舊 | 升級工具或手動執行 SET NAMES utf8mb4 |
| CSDN/博客編輯器存入截斷 | 後端數據庫/連接未全鏈路 utf8mb4 | 排查全鏈路:DB、表、列、連接池、驅動、應用代碼 |
索引長度報錯 Specified key was too long | utf8mb4 4 字節/字符,VARCHAR(255) 索引超 767 字節限制 (5.6.3- / innodb_large_prefix=OFF) | 1) 升級 5.7+ / 開啟 innodb_large_prefix=ON 2) 縮短列長度 VARCHAR(191) 3) 升級 8.0 (默認 3072 字節) |
排序規則報錯 Unknown collation: utf8mb4_0900_ai_ci | MySQL 5.7 不支持 0900 排序規則 | 用 utf8mb4_unicode_ci 或 utf8mb4_general_ci |
MySQL 支持 Emoji 的本質是 **全鏈路 utf8mb4**:
Server 配置 → 庫表列轉換 → 連接池/驅動 → 應用代碼 → 客戶端工具,缺一環即失效。
新項目**直接初始化 utf8mb4**,存量項目按「庫 → 表 → 列」分批遷移,**大表必走 pt-osc/gh-ost**。
將字符集治理納入架構治理體系,定期掃描information_schema.COLUMNS發現非 utf8mb4 列自動工單修復。