日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

字符集GBK升级UTF8

發布時間:2024/9/20 编程问答 38 豆豆
生活随笔 收集整理的這篇文章主要介紹了 字符集GBK升级UTF8 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

? ? ?在生產環境中,數據庫字符集因為各種原因需要升級,比如為了支持漢字,從latin1字符集升級到GBK,后面為了支持多個語言文字,需要將GBK升級到UTF8等。遷移過程網上有很多,我今天主要想講下字符集轉換后,可能對業務產生的影響,我以GBK轉換到UTF8為例說明。主要有兩點:

  • 漢字在GBK編碼中占2個字節,在UTF8編碼中占3個字節,而mysql的索引要求總長度不超過767個字節,因此索引字符數會被縮短(383->255),特別的,對于唯一索引,要求索引字段長度小于256個字符。
  • 編碼轉換后,導致字段排序發生變化。
  • 這篇文章主要為了說明編碼轉換后,字段排序如何受影響,會結合mysql源代碼給出原因和分析。首先看測試用例,假設cmp_t(GBK編碼)和cmp_t2(UTF8編碼)分別是遷移前后的表。

    測試用例:

    ?

    操作

    cmp_t(GBK)

    cmp_t2(UTF8)

    1

    ?

    GBK表:

    select?c1,hex(c1) from?cmp_t;

    ?

    UTF8表:

    select?c1,hex(c1) from cmp_t2;

    +------+---------+

    | c1???|?hex(c1) |

    +------+---------+

    |?一??| D2BB???

    |?二??| B6FE

    |?三??| C8FD???

    |?a????| 61?????

    | 1????| 31

    +------+---------+?????

    +------+---------+

    | c1???|?hex(c1) |

    +------+---------+

    |?一??| E4B880?

    |?二??| E4BA8C?

    |?三??| E4B889?

    |?a????| 61?????

    | 1????| 31?????

    +------+---------+

    2

    GBK表:

    select?c1,hex(c1) from?cmp_t?where c1>’a’ order by c1;

    ?

    UTF8表:

    select?c1,hex(c1) from cmp_t2 where c1>’a’ order by c1;

    +------+---------+

    | c1???|?hex(c1) |

    +------+---------+

    |???| B6FE????|

    |???| C8FD???

    |???| D2BB???

    +------+---------+

    +------+---------+

    | c1???|?hex(c1) |

    +------+---------+

    |???| E4B880?

    |???| E4B889?

    |???| E4BA8C?

    +------+---------+

    ?

    從上面操作返回的結果我們可以得到以下幾點信息:

  • 漢字在GBK編碼中占2個字節,在UTF8編碼中占3個字節
  • 數字和英文字符在GBK和UTF8編碼中都只占一個字節
  • 漢字在UTF8編碼和GBK編碼不同,排序后順序變化了。
  • 原理分析:

    Mysql利用sortcmp函數對字符串進行比較,對于GBK的字符串和UTF8的字符串分別采用接口my_strnncollsp_gbk和my_strnncollsp_utf8比較,這兩個函數分別在ctype-gbk.c和ctype-utf8.c中實現,兩個函數實現邏輯類似,只是各有自己一套比較大小的規則,下面我主要描述下my_strnncollsp_utf8的比較邏輯和比較大小的規則。

    比較邏輯:

  • 獲取字符串的第一個字節
  • 根據UTF8的編碼規則(附1),確定字符由幾個字節組成
  • 根據一定的算法算出字符的加權值(附2),比較大小;若不符合UTF8編碼規范,認為是亂碼,采用二進制比較(附3)
  • 跳過步驟2返回的字節數,比較下一個字符。
  • 附1:【接口: my_utf8_uni】

    根據UTF8編碼規則,符合編碼規范的字符占用1-6個字節。

    取字符串第一個字節?s

    if?s<0x80

    ? ? ?表示字符占1個字節

    elif?s<0xe0

    ? ? 表示字符占2個字節

    elif?s<0xf0??

    ? ? 表示字符占3個字節

    else?s<0xf8

    ? ? 表示字符占4個字節

    elif?s<0xfc

    ? ?表示字符占5個字節

    elif?s<0xfe

    ? ?表示字符占6個字節?

    英文字符和數字字符編碼兼容ASCII,編碼值小于0x80,因此都只占1個字節;漢字的utf8編碼的首字節都在[0xe0,0xf0]之間,所以占3個字節。

    附2:utf8編碼比較大小規則

    value?= ((s[0] & 0x0f) << 12)| ((s[1] ^ 0x80) << 6) | (s[2] ^ 0x80)

    s[0],s[1],s[2]表示組成漢字的三個字節,對參與比較的漢子字符進行計算得到value1和value2,通過比較value1和value2的大小,判斷字符大小。

    附3:二進制比較【接口:?bincmp】

    memcmp函數比較,即逐字節比較。

    因此,如果業務上面需要依賴漢字比較的場景,需要考慮字符集升級(GBK->UTF8)的風險,主要是索引或主鍵中包含字符串字段需要特別關注,如果字符串中確定只包含有數字和字符,則不會存在問題。

    ?

    ?

    ?

    總結

    以上是生活随笔為你收集整理的字符集GBK升级UTF8的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。