mysql> SELECT name FROM user WHERE id=1;
+----------+
| name |
+----------+
| ?????? | -- 亂碼
+----------+
MySQL 涉及三個字符集層級:
**亂碼本質:** 三者任意兩層不一致即產生亂碼。
mysql> SET NAMES gbk; -- 告訴服務器:我發送 GBK,請返回 GBK
Query OK, 0 rows affected
mysql> SELECT name FROM user WHERE id=1;
+--------+
| name |
+--------+
| 張三 | -- 正常顯示 (前提:終端也是 GBK)
+--------+
`SET NAMES gbk` 等同於:
SET character_set_client = gbk;
SET character_set_connection = gbk;
SET character_set_results = gbk;
[client]
default-character-set = utf8mb4
[mysql]
default-character-set = utf8mb4
[mysqld]
character-set-server = utf8mb4
collation-server = utf8mb4_unicode_ci
init_connect = 'SET NAMES utf8mb4' -- 非超級用戶連接自動執行
[mysql]
default-character-set = utf8mb4
[mysqld]
character-set-server = utf8mb4
重啟服務生效:`systemctl restart mysqld` / `net stop mysql && net start mysql`。
mysql> SHOW VARIABLES LIKE 'character_set_%';
+--------------------------+---------+
| Variable_name | Value |
+--------------------------+---------+
| character_set_client | utf8mb4 |
| character_set_connection | utf8mb4 |
| character_set_database | utf8mb4 |
| character_set_results | utf8mb4 |
| character_set_server | utf8mb4 |
| character_set_system | utf8 |
+--------------------------+---------+
-- PHP PDO (推薦)
$dsn = "mysql:host=localhost;dbname=test;charset=utf8mb4";
-- Java JDBC 8.0+
url = "jdbc:mysql://localhost:3306/test?characterEncoding=utf8mb4&useSSL=false&serverTimezone=Asia/Shanghai";
-- Python PyMySQL
conn = pymysql.connect(host='localhost', user='root', password='', db='test', charset='utf8mb4')