軟件測試開發技術MySQL亂碼問題深層分析 MySQL數據庫
關鍵字:MySQ L亂碼
【IT168 技術文章】
一、概述
公司新購了一批PC,準備把幾個性能較優的PC升級為數據庫服務器,替換老舊的機器。公司有套POS終端軟件,后臺數據存儲是 MySQL 3.23 版。我準備硬件升級的同時升級數據庫軟件。但是升級過程中遇到聞名的 MySQL 的亂碼問題。經過查找資料,加上自己的摸索和經驗,終于完美地解決這個問題。
MySQL 的亂碼問題(不僅僅包括中文亂碼,也包括其它語言的亂碼,以下稱之為亂碼問題)只存在于4.1及其以上版本。4.1之前的 MySQL 不支持多語言,所以它會將你給它的數據“原封不動”地保存,再“原封不動”地讀出來。從字節的角度來看,數據在這一過程中不會產生任何變化,因此不會有亂碼。
4.1及以后的版本開始支持多語言,這個所謂的多語言,就是在輸入輸出時 MySQL 會替你做編碼轉換。而這個轉換規則就是由客戶端編碼和服務器端編碼來決定的。
編碼轉換的規則就是,在輸入數據時將編碼由“客戶端編碼”轉換為“服務器端編碼”,輸出時將數據由“服務器端編碼”轉換為“客戶端編碼”。
二、亂碼產生原因
MySQL 字符編碼是版本4.1引入的,支持多國語言,而且一些特性已經超過了其它大多數數據庫管理系統。正因為這一特性才導致 MySQL 的亂碼問題。
字符集是一套符號和編碼。校對規則是在字符集內用于比較字符的一套規則。讓我們使用一個假想字符集的例子來區別清楚。
假設我們有一個字母表使用了四個字母:‘A’、‘B’、‘a’、‘b’。我們為每個字母賦予一個數值:‘A’=0,‘B’= 1,‘a’= 2,‘b’= 3。字母‘A’是一個符號,數字0是‘A’的編碼,這四個字母和它們的編碼組合在一起是一個字符集。
假設我們希望比較兩個字符串的值(在if……else語句中我們經常做值的比較):‘A’和‘B’。比較的最簡單的方法是查找編碼:‘A’為0,‘B’為1。因為0 小于1,我們可以說‘A’小于‘B’。我們做的僅僅是在我們的字符集上應用了一個校對規則。校對規則是一套規則(在這種情況下僅僅是一套規則):“對編碼進行比較?!蔽覀兎Q這種全部可能的規則中的最簡單的校對規則為一個binary(二元)校對規則。
但是,如果我們希望小寫字母和大寫字母是等價的,應該怎樣?那么,我們將至少有兩個規則:(1)把小寫字母‘a’和‘b’視為與‘A’和‘B’等價;(2)然后比較編碼。我們稱這是一個大小寫不敏感的校對規則。比二元校對規則復雜一些。
原文轉自:http://www.anti-gravitydesign.com