mysql資料校驗過程中的字符集問題處理

2022-09-28 21:42:23 字數 2147 閱讀 1292

場景:

主庫db:utphgjwbrvwpf8字符集

備庫db:gbk字符集

需求:校驗主備資料是否一致,並且修復

校驗過程:

設定主庫連線為utf8,設定備庫連線為gbk,分別進行查詢,將返回的的結果集按記錄逐字段比較。

顯示結果:

原本相同的漢字字元,資料校驗認為不一致。

原因分析:

對於主庫而已,由於建立連線的字符集為utf8,則返回的漢字字元編碼為utf8格式;對於備庫而言則是gbk格式,而程式中通過字串比較函式strcasecmp進行比較,顯然不同的字符集編碼,相同的字元有不同的二進位制,因此結果肯定不會相等。

進一步分析:

那麼對於這種情況,建立連線應該採用哪種字符集呢?gbk or utf8。其實phgjwbrvwp選擇任何一程式設計客棧種字符集都是ok的,只要是訪問主庫和備庫的字符集保持一致即可,唯一的區別在於,若選擇的字符集與客戶端的字符集不一致,可能導致無法正常顯示字元,即字元顯示為亂碼。

我們以客戶端的字符集為例,詳細說說三種情況:【這裡的客戶端可以認為是securecrt】

備註:綠色框代表db字符集,黃色框代表連線字符集,橙色框代表客戶端

第一種情況:

就是上述的情況,主庫返回字元的gbk編碼,備庫返回字元的utf8編碼,因此進行欄位比對,則會出現誤差。

第二種情況:

訪問主庫的連線不變,備庫連線由utf8變為gbk,因此進行返回時,資料庫會將db的字符集轉為gbk返回給客戶端,那麼對於客戶端而已,相同字元都是通過gbk編碼表示,因此二進位制相等,校驗結果正確。

第三種情況:

訪問主庫和備庫的連線都是utf8,因此對於主庫而已,返回給客戶端的字元編碼由gbk轉為utf8,此時主庫和備庫都是utf8編碼,校驗結果正確。但由於客戶端實質是gbk編碼方式顯示,因此返回的漢字字元都是亂碼,但不影響校驗結果的正確性。

修復:      既然選擇與主備庫任一乙個相同的字符集去訪問,都不會影響校驗結果的正確性,那麼影響修復呢?由於utf8的編碼範圍比gbk編碼範圍要大,因此若採用gbk連線訪問utf8編碼db,有可能出現部分字元gbk不能表示的情況。

我們拿第二種情況說明,此時主庫為gbk,備庫為utf8,使用gbk訪問utf8。假設存在utf8轉為gbk過程中部分字元丟失,這時候主備庫肯定是不一致的,因為存在部分字元gbk無法表示。 假設修復語句如下:

update  t set c1=www.cppcns.commaster_value  where  c1=sl**e_value  and id=?

其中t表示表名,id是主鍵表示某一行,master_value為主庫c1列的值,sl**e_value為備庫c1列的值。此時,sl**e_value由於utf8轉為gbk已經丟失,因此語句執行最終影響0行記錄,無法修復。

結論:客戶端訪問兩個不同字符集庫進行資料校驗時,連線採用表示範圍更大的字符集。比如我們常用的字符集表示範圍如下:

latin

附:mysql客戶端與伺服器通訊時字符集編碼轉換流程

相關引數:

– character_set_client:客戶端**資料使用的字符集

– character_set_connection:連線層字符集

– char程式設計客棧acter_set_results:查詢結果字符集

– character_set_database:當前選中資料庫的預設字符集

– character_set_system:系統元資料(欄位名等)字符集

1.客戶端請求伺服器

1)將client的字符集轉為connection字符集

2)將connection字符集轉為db內部的字符集

2.伺服器返回結果給客戶端

1)將db內部字符集轉為connection字符集

2)將connection字符集轉為character_set_results字符集

3.設定字符集命令:set names 字元編碼

指定客戶端與伺服器通訊的字符集,包括請求與返回。

set names 'x'  等價於:

set character_set_client = x;

set character_set_results = x;

set character_set_connection = x;

附圖:本文標題: mysql資料校驗過程中的字符集問題處理

本文位址:

Mysql儲存過程中字串分割

今在專案中碰到了要把字串分割,記錄下來,以後可能還用的到 首先想上我的儲存過程 delimiter use bplate drop procedure if exists lp plate insertplateinfo create definer root localhost procedure...

mysql儲存過程中遍歷json資料

一 今天在開發中遇到mysql中遍歷json資料的需求,查了些資料,然後特此記錄,二 在mysql5.7中是有乙個方法用來取json資料的,json extract json.val,key 詳細 如下 三 如下 create definer root localhost procedure fun...

MySQL過程中遇到的問題

my.ini檔案中搜尋mysqld關鍵字,在下面新增skip grant tables 我的my.ini配置如下 client 設定客戶端埠號 port 3306 設定預設資料編碼格式 default character set utf8 mysqld skip grant tables 設定為自己...