程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 數據庫知識 >> MYSQL數據庫 >> MySQL綜合教程 >> 淺談MySQL備份字符集的問題

淺談MySQL備份字符集的問題

編輯:MySQL綜合教程

1 引子

MySQL備份時選擇字符集是一個難題,特別是字符集不定的業務。mysqldump默認使用utf8,而官方也推薦使用utf8。但實際上,對於中文,部分相當一部分gbk編碼字符沒有對應的unicode編碼,也就是說這部分字符集使用utf8備份會導致數據丟失。那麼有沒有解決方法呢?

當然,最直接的方法是將這部分編碼的映射加上。但是,這部分的字符集數量並不是少數,而且,更蛋疼的是,似乎找不到這部分字符集權威的映射標准。那麼,還有其它方法嗎?

實際上,如果使用binary進行備份,就不會存在字符集的轉換過程,也就不會存在上述問題。那麼,使用binary是否就解決了gbk所有的問題呢?答案是NO。

2 binary的問題

在講binary的問題之前。需要弄清2個問題。對於MySQL備份,分兩部分:schema信息和實際數據。而Schema信息一律使用utf8編碼,但是,default value除外。這正是問題的來源。

 

2.1 utf8備份

(1)文件.frm會存儲table的schema信息,並通過一個實際的記錄來存儲各個field的默認值。Schema對應的信息(包括comment)使用utf8存儲,但是default value使用table指定的字符集進行存儲。

(2)當執行show create table語句時,mysqld會將frm中的默認值從table指定的編碼轉成utf8編碼。

(3)當mysqld執行create table語句,會將default value從utf8轉成table指定的字符集。

 

2.2 binary備份

如果指定binary進行備份。在導入時,在創建table之前,雖然將character_set_client指定為utf8,但collation_connection還是binary。所以,存儲默認值時不會進行utf8到table指定的字符集的轉換。如果table指定為gbk編碼,導入必然失敗。

示例:

CREATE TABLE `t1`(

`iNetbarId` int(11) NOT NULL DEFAULT '0',

`iUin` bigint(20) NOT NULL DEFAULT '0',

`vNetbarName` varchar(80) NOT NULL DEFAULT '“-”',

PRIMARY KEY (`iNetbarId`)

) ENGINE=InnoDB DEFAULT CHARSET=gbk;

 

insert into t1 values(1,1,'xxxx');

clip_image002

可以看到,正常導出的表,導入卻出現1067 Invalid default value的錯誤。

3 解決方法

mysqldump時,在執行create table語句之前,增加對character_set_connection 的設置。

/*!40101 SET character_set_connection = utf8 */

clip_image004

clip_image006

這也算是MySQL一個bug,既然schema信息從頭到尾都使用utf8,在執行create table之前,就應該將連接的字符集變量設置成utf8,而不是只設置client的字符集變量。


  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved