MySQL 預設字元集常為 latin1,導致中文存入變亂碼。在 Ubuntu 上透過 apt 安裝 MySQL 後,需修改設定檔強制使用 UTF-8(或 utf8mb4 支援 Emoji)。
# 透過 apt 安裝的預設路徑
/etc/mysql/my.cnf
# 找不到時,搜尋所有 .cnf
sudo find / -iname '*.cnf' 2>/dev/null
常見位置:/etc/mysql/my.cnf、/etc/mysql/mysql.conf.d/mysqld.cnf、/etc/my.cnf。
sudo cp /etc/mysql/my.cnf /etc/mysql/my.cnf.bak
sudo vim /etc/mysql/my.cnf
在對應區段下新增/修改:
[mysqld]
# 伺服器端字元集
character-set-server = utf8mb4
collation-server = utf8mb4_unicode_ci
# 避免隱性轉換
skip-character-set-client-handshake
[client]
# 客戶端預設字元集
default-character-set = utf8mb4
[mysql]
# mysql 指令列工具
default-character-set = utf8mb4
[mysqldump]
# 備份工具
default-character-set = utf8mb4
說明: 推薦使用 utf8mb4(支援 4 位元組字符,含 Emoji、生僻字),utf8 為 3 位元組子集,舊專案相容可用 utf8 / utf8_general_ci。
# systemd 管理(Ubuntu 16.04+)
sudo systemctl restart mysql
# 或
sudo service mysql restart
# 傳統 init.d
sudo /etc/init.d/mysql restart
mysql -u root -p
# 登入後執行
SHOW VARIABLES LIKE 'char%';
預期輸出關鍵變數皆為 utf8mb4:
+--------------------------+----------------------------+
| Variable_name | Value |
+--------------------------+----------------------------+
| character_set_client | utf8mb4 |
| character_set_connection | utf8mb4 |
| character_set_database | utf8mb4 |
| character_set_filesystem | binary |
| character_set_results | utf8mb4 |
| character_set_server | utf8mb4 |
| character_set_system | utf8mb4 |
| character_sets_dir | /usr/share/mysql/charsets/ |
+--------------------------+----------------------------+
CREATE DATABASE test_db CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
USE test_db;
CREATE TABLE t (c VARCHAR(100)) CHARSET=utf8mb4;
INSERT INTO t VALUES ('測試中文😀Emoji');
SELECT * FROM t;
若正常顯示中文與 Emoji,設定成功。
# 資料庫層級
ALTER DATABASE db_name CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci;
# 資料表層級(含欄位)
ALTER TABLE tbl_name CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
# 僅修改欄位定義不轉換資料(慎用)
ALTER TABLE tbl_name MODIFY col_name VARCHAR(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
my.cnf 後必須重啟 MySQL 才生效。?characterEncoding=utf8mb4、PHP PDO charset=utf8mb4、Python charset='utf8mb4'。skip-character-set-client-handshake 強制伺服器端字元集,忽略客戶端請求,避免不一致,但可能衝突舊應用,視情況啟用。設定一次,永久告別中文亂碼與 Emoji 存不進去的困擾。