首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫

解決 MySQL UTF-8 亂碼與「Unknown system variable 'names'」錯誤

     編輯:MySQL 資料庫相關知識

問題現場還原

在某共享主機(萬網)環境下,嘗試執行 SET NAMES 'utf-8' 解決中文亂碼,卻報錯:

#1193 - Unknown system variable 'names'

同時所有字符集相關操作(SET CHARSET、SET COLLATION 等)全部失效。

根因深度剖析

1. 語法錯誤:SET NAMES vs SET NAMES

  • 正確語法:SET NAMES utf8mb4(無引號、無連字號)
  • 錯誤寫法:SET NAMES 'utf-8' → MySQL 將 'utf-8' 視為字串字面值,嘗試設定名為 names 的系統變數,導致 1193 錯誤

2. 共享主機權限鎖死

  • 虛擬主機通常禁用 SUPER 權限,導致無法執行 SET GLOBAL character_set_server 等全域變更
  • 部分老舊面板(cPanel/DirectAdmin)鎖定 my.cnf,無法修改 character-set-server 預設值
  • PHPMyAdmin 版本過舊(< 4.0),預設連線字符集為 latin1

3. MySQL 版本與字符集支援差異

分層解決方案

層級 1:應用程式碼層(最高優先級,不依賴主機權限)

// PHP PDO(推薦)
$pdo = new PDO("mysql:host=$host;dbname=$db;charset=utf8mb4", $user, $pass, [
    PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
    PDO::MYSQL_ATTR_INIT_COMMAND => "SET NAMES utf8mb4 COLLATE utf8mb4_unicode_ci"
]);

// PHP mysqli
$mysqli->set_charset("utf8mb4");
// 或
$mysqli->query("SET NAMES utf8mb4 COLLATE utf8mb4_unicode_ci");

層級 2:連線參數層(DSN 指定)

# PHP PDO DSN
mysql:host=localhost;dbname=test;charset=utf8mb4

# JDBC URL
jdbc:mysql://host:3306/db?characterEncoding=utf8&useSSL=false&serverTimezone=Asia/Taipei

# Python PyMySQL
conn = pymysql.connect(charset='utf8mb4')

層級 3:資料庫物件層(建表時指定)

CREATE DATABASE mydb 
  DEFAULT CHARACTER SET utf8mb4 
  DEFAULT COLLATE utf8mb4_unicode_ci;

CREATE TABLE t1 (
  id INT PRIMARY KEY,
  name VARCHAR(100)
) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;

-- 修改現有表
ALTER TABLE t1 CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;

層級 4:伺服器配置層(需主機商協助或 VPS 權限)

[mysqld]
character-set-server = utf8mb4
collation-server = utf8mb4_unicode_ci
init_connect = 'SET NAMES utf8mb4 COLLATE utf8mb4_unicode_ci'
skip-character-set-client-handshake  # 強制忽略客戶端字符集請求

驗證檢查清單

-- 1. 檢查連線字符集
SHOW VARIABLES LIKE 'character_set_%';
SHOW VARIABLES LIKE 'collation_%';

-- 2. 實測中文寫入讀取
CREATE TABLE test_charset (c VARCHAR(20)) CHARSET utf8mb4;
INSERT INTO test_charset VALUES ('測試中文😀');
SELECT c, HEX(c), CHAR_LENGTH(c), LENGTH(c) FROM test_charset;
-- 正確應顯示:測試中文😀 | E6B8ACE8AF95E4B8ADE69687F09F9880 | 6 | 19

避坑指南:為何不建議使用「utf-8」

  • MySQL 的 utf8 別名實為 utf8mb3,僅支援 BMP 平面(3 字節),無法儲存 Emoji、生僻字(需 4 字節)
  • 必須使用 utf8mb4 才能完整支援 Unicode 所有字符
  • 連字號 utf-8 僅是 IANA 註冊名,MySQL 內部不識別,切勿在 SQL 中使用

給共享主機用戶的建議

  1. 優先選擇支援 utf8mb4 且開放 SET NAMES 的主機商
  2. 若主機商鎖死字符集且拒絕調整,立即遷移——這是基礎技術能力的底線
  3. 使用 mysqldump --default-character-set=utf8mb4 導出遷移,避免雙重編碼損壞
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved
版本預設字符集utf8mb4 支援備註
5.1 / 5.5latin15.5.3+ 引入需手動指定 utf8mb4
5.6 / 5.7latin1完整支援建議 my.cnf 設定預設
8.0+utf8mb4原生預設collation 預設 utf8mb4_0900_ai_ci