著重基礎之—MySql Blob類型和Text類型
著重基礎之—MySql Blob類型和Text類型—二進制存儲
在經歷了幾個Java項目後,遇到了一些問題,在解決問題中體會到基礎需要不斷的回顧與鞏固。
最近做的項目中,提供給接口調用方數據同步接口,傳輸的數據格式是Json串。由於json串的結構層級較多,數據量也不少。在設計數據庫的時候,選擇了Blob類型做為字段類型。一切的一切就打這開始,同步服務正常運作,但是問題慢慢的暴露了出來,客戶端在暫時我所提供的數據的時候,中文總是顯示亂碼,亂碼,亂碼,一直亂碼。
問題的分析路徑
1.查看了數據庫連接字符串,characterEncoding=utf8 ,配置正常。
2.詢問接口調用方,編碼格式一致,utf8。
3.查看數據庫編碼格式,utf8,正常。
4.查看數據表編碼格式,utf8,正常。
然後問題依然存在,中文數據通過查詢腳本查出來的結果都顯示正常,但是一到網頁上依然是亂碼,亂碼。於是把線上的數據導出到本地一份,接著觀察,發現中文亂碼處可以看出,一個中文被3個字節所代替,考慮到utf8編碼格式下,一個中文占3個字節,問題的原因初步可以斷定是數據的存儲格類型引起的。然後查閱了Mysql Blob 類型的說明,Blob存儲的其實是二進制數據,我們來看看Blob的定義:
BLOB是一個二進制大對象,可以容納可變數量的數據。有4種BLOB類型:TINYBLOB、BLOB、MEDIUMBLOB和LONGBLOB。它們只是可容納值的最大長度不同。BLOB 列被視為二進制字符串(字節字符串)。BLOB列沒有字符集,並且排序和比較基於列值字節的數值值。我們再來看看常用的大文本類型Text的定義,這樣能有一個對比。
TEXT列被視為非二進制字符串(字符字符串),TEXT列有一個字符集,並且根據字符集的校對規則對值進行排序和比較。
通常Mysql 字符集的配置就告訴了Mysql在執行查詢時所呈現的編碼格式,就拿Blob中存儲的二進制數據舉例來說:在mysql 控制臺執行查詢命令時,控制臺自身就幫我們完成了由字節到文本的轉換,相應地中文也進行了正常的轉換。記得,此處我們強調了mysql控制臺,或者說就是我們常用的shell命令,mysql -u *** -p 腳本執行的控制臺環境。字節——文本的轉換Mysql 控制臺按照utf8的編碼格式進行了轉換。 這也是為什麽我們登陸到mysql服務後,mysql -u *** -p 登陸mysql服務器後,執行查詢腳本的到正常數據的原因。
那麽為什麽通過程序連接mysql返回的結果不對呢,是因為java程序連接mysql執行查詢後,Blob類型本身是沒有字符集的,也就不會做根據字符集的校對,所以java連接mysql執行查詢返回的Byte[]字節數組是沒有經過任何字符集校隊的,即便你存入Blob的數據本身就是符合utf8編碼格式的,最終得到的結果依然會是亂碼,除非你在程序中有相應的處理邏輯。
好了,到這終於解決了中文亂碼展示的問題,同時也明白了亂碼出現的原因。對Blob類型的認識也更加深刻。
小提示:如果你的BLOB中存儲的數據原本就是符合utf8編碼格式的,同時你的數據庫以及數據表的編碼格式的符合utf8,那麽字段類型由BLOB變更為Text類型時,數據時可是保證正常轉換的,當然,別忘記了字段長度要保持一個量級。這個我自己測試了下,沒有問題。
著重基礎之—MySql Blob類型和Text類型