首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 數據庫知識 >  >> MySQL 資料庫 >> MySQL 綜合教學

MySQL 5.0.16 亂碼問題根因分析與解決方案

     編輯:MySQL 綜合教學

版本背景

MySQL 5.0.16 (2005 年釋出) 預設字符集為 latin1,不支援 utf8mb4 (需 5.5.3+),且連線層字符集協商機制尚未完善。若您仍在維護此版本,以下方案可解決中文亂碼。

核心問題

  • Server/Database/Table/Column 預設皆為 latin1,中文被視為單字節儲存,實際為雙字節 (BIG5/GBK) 或三字節 (UTF-8) 導致截斷/誤讀。
  • 客戶端連線未指定字符集,驅動預設 latin1,造成「存進去是一組碼,讀出來是另一組碼」。

解決方案:統一使用 UTF-8 (utf8 別名 utf8mb3)

1. 修改 my.cnf (Linux) / my.ini (Windows)

[mysqld]
default-character-set = utf8
character-set-server = utf8
collation-server = utf8_general_ci
init_connect = 'SET NAMES utf8'

[client]
default-character-set = utf8

[mysql]
default-character-set = utf8

重啟服務生效。

2. 資料庫與表層級明確指定

CREATE DATABASE mydb DEFAULT CHARACTER SET utf8 COLLATE utf8_general_ci;
CREATE TABLE users (
  id INT PRIMARY KEY,
  name VARCHAR(50) CHARACTER SET utf8 COLLATE utf8_general_ci
) DEFAULT CHARACTER SET utf8 COLLATE utf8_general_ci;

3. 既有 latin1 表轉換 (資料已為 UTF-8 位元組但標記為 latin1)

此情況最常見:應用寫入 UTF-8 位元組,但欄位標記 latin1。轉換步驟:

-- 1. 將欄位改為 BLOB (二進位,不做字符集轉換)
ALTER TABLE users CHANGE name name BLOB;
-- 2. 再改回 VARCHAR 並指定 utf8
ALTER TABLE users CHANGE name name VARCHAR(50) CHARACTER SET utf8 COLLATE utf8_general_ci;

若資料真的是 BIG5/GBK 編碼,需用 CONVERT TO CHARACTER SET utf8 讓 MySQL 做碼表轉換。

4. 連線層強制指定

  • JDBC (Connector/J 3.1+): jdbc:mysql://host/db?useUnicode=true&characterEncoding=utf8
  • PHP (mysqli): mysqli_set_charset($link, 'utf8');
  • Python (MySQLdb): conn.set_character_set('utf8')
  • 通用 SQL: 連線後立即執行 SET NAMES 'utf8'; (等同 SET character_set_client, connection, results = utf8)

驗證方法

SHOW VARIABLES LIKE 'character_set_%';
SHOW VARIABLES LIKE 'collation_%';
-- 期望輸出:
-- character_set_client     utf8
-- character_set_connection utf8
-- character_set_results    utf8
-- character_set_server     utf8
-- character_set_database   utf8
-- collation_connection     utf8_general_ci
-- collation_server         utf8_general_ci
-- collation_database       utf8_general_ci

若 client/connection/results 非 utf8,檢查驅動設定或 init_connect 是否對 super 用戶生效 (super 用戶不執行 init_connect,需應用層自行 SET NAMES)。

常見誤區

誤區正確觀念
以為 SET NAMES 只影響當前 Session確實只影響當前 Session,故必須在連線池初始化或每次取連線時執行
使用 utf8_general_ci 以為支援所有 UnicodeMySQL 5.0 的 utf8 僅支援 BMP (U+0000~U+FFFF),不支援 Emoji (需 5.5.3+ utf8mb4)
直接 ALTER TABLE ... CONVERT TO utf8 卻資料變亂碼若原資料實為 UTF-8 位元組但標記 latin1,CONVERT 會再做一次 latin1→utf8 轉換導致雙重編碼,必須用 BLOB 中轉法

升級建議

MySQL 5.0 已於 2011 年結束生命週期,無安全性更新、無 utf8mb4、優化器功能落後。強烈建議規劃升級至 5.7 / 8.0 / MariaDB 10.x,並同步調整字符集為 utf8mb4 + utf8mb4_0900_ai_ci。

結語

MySQL 5.0.16 亂碼核心在於「預設 latin1」與「連線未指定字符集」。透過 my.cnf 統一 utf8、表欄位明確指定、既有資料 BLOB 中轉、應用層強制 SET NAMES utf8,即可徹底解決中文儲存與查詢問題。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved