MySQL 中文建表亂碼的核心原因是「建表字元集 latin1」與「插入資料 utf8」不匹配,導致 Data too long for column 或亂碼。本文實戰演示「建庫→設定連線字元集→建表指定 utf8mb4」全鏈路配置,徹底解決中文存儲與導入導出問題。
mysql> CREATE TABLE person (id INT PRIMARY KEY, name VARCHAR(16)) ENGINE=InnoDB;
mysql> SET NAMES utf8;
mysql> INSERT INTO person VALUES (1, '張三'); -- 中文 2 字元,latin1 視為 6 位元組,超過 VARCHAR(16) 位元組限制
ERROR 1406 (22001): Data too long for column 'name' at row 1
根因:VARCHAR(16) 在 latin1 下限制 16 位元組,UTF-8 中文佔 3 位元組,實際只能存 5 個中文字。
CREATE DATABASE test DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
SET NAMES utf8mb4;
-- 等同於
SET character_set_client = utf8mb4;
SET character_set_connection = utf8mb4;
SET character_set_results = utf8mb4;
CREATE TABLE person (
id INT NOT NULL AUTO_INCREMENT PRIMARY KEY,
name VARCHAR(16) DEFAULT 'nobody',
birthday CHAR(19)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
mysql> SET NAMES utf8mb4;
mysql> INSERT INTO person (name, birthday) VALUES ('張三豐', '2023-01-01 12:00:00');
Query OK, 1 row affected (0.01 sec)
mysql> SELECT * FROM person;
+----+-----------+---------------------+
| id | name | birthday |
+----+-----------+---------------------+
| 1 | 張三豐 | 2023-01-01 12:00:00 |
+----+-----------+---------------------+
| 層級 | 配置項 | 推薦值 | 驗證指令 |
|---|---|---|---|
| 伺服器 | character-set-server | utf8mb4 | SHOW VARIABLES LIKE 'character_set_server'; |
| 資料庫 | DEFAULT CHARACTER SET | utf8mb4 | SHOW CREATE DATABASE db; |
| 表 | DEFAULT CHARSET | utf8mb4 | SHOW CREATE TABLE tbl; |
| 欄位 | CHARACTER SET | utf8mb4(可繼承表) | SHOW FULL COLUMNS FROM tbl; |
| 連線 | SET NAMES / connectionInitSql | utf8mb4 | SHOW VARIABLES LIKE 'character_set_%'; |
| 應用 | JDBC/ODBC/ORM 連線參數 | characterEncoding=utf8mb4 | 檢查連線 URL/配置檔 |
utf8 實為 utf8mb3(最多 3 位元組),不支援 Emoji/生僻字,**必須用 utf8mb4**。connectionInitSql=SET NAMES utf8mb4,確保每條連線自動設定。mysqldump --default-character-set=utf8mb4 ... | mysql --default-character-set=utf8mb4 避免導入亂碼。ALTER TABLE tbl CONVERT TO CHARACTER SET utf8mb4(轉換資料),而非 ALTER TABLE tbl CHARACTER SET utf8mb4(僅影響新資料)。