mysql gbk转utf8_MySQL字符集GBK转换到UTF8
在生产环境中,MySQL数据库字符集因为各种原因需要升级,比如为了支持汉字,从latin1字符集升级到GBK,后面为了支持多个语言文字,需要将GBK升级到UTF8等。迁移过程网上有很多,我今天主要想讲下字符集转换后,可能对业务产生的影响,我以GBK转换到UTF8为例说明。
主要有两点:
1.汉字在GBK编码中占2个字节,在UTF8编码中占3个字节,而mysql的索引要求总长度不超过767个字节,因此索引字符数会被缩短(383->255),特别的,对于唯一索引,要求索引字段长度小于256个字符。
2.编码转换后,导致字段排序发生变化。
这篇文章主要为了说明编码转换后,字段排序如何受影响,会结合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)的风险,主要是索引或主键中包含字符串字段需要特别关注,如果字符串中确定只包含有数字和字符,则不会存在问题。
mysql gbk转utf8_MySQL字符集GBK转换到UTF8相关推荐
- mysql中gbk编码汉字和英文_MySQL字符集 GBK、GB2312、UTF8区别 解决 MYSQL中文乱码问题...
MySQL中涉及的几个字符集 character-set-server/default-character-set:服务器字符集,默认情况下所采用的. character-set-database:数 ...
- mysql utf8和gbk的区别_MySQL字符集 GBK、GB2312、UTF8区别
MySQL中涉及的几个字符集 character-set-server/default-character-set:服务器字符集,默认情况下所采用的. character-set-database:数 ...
- mysql gbk编码 转utf8_MySQLGBKUTF-8 编码转换
MySQLGBKUTF-8 编码转换 前言: 第一次写教程, 其实算不得教程, 只是想总结个转换的手记如果中间有错误, 或者办法不够理想, 大家回贴研究下 另外, 我也希望我们论坛不仅仅作为闲聊的地方 ...
- mysql gbk_MySQL字符集 GBK、GB2312、UTF8区别 解决MYSQL中文乱码问题
MySQL字符集 GBK.GB2312.UTF8区别 解决MYSQL中文乱码问题 更新时间:2012年08月27日 21:17:11 作者: MYSQL中文乱码问题原因有很多,脚本之家以前发布过很 ...
- MySQL数据库从GBK转换到UTF-8最简单解决方案(也适用于其它编码转换)
MySQL数据库从GBK转换到UTF-8最简单解决方案(也适用于其它编码转换) 参考文章: (1)MySQL数据库从GBK转换到UTF-8最简单解决方案(也适用于其它编码转换) (2)https:// ...
- mysql 数据库是utf8 用cms gbk 可以吗_帝国cms编码GBK转换成UTF-8版教程方法
注意事项: 转换前先备份下数据库以及d附件目录 转换步骤: 1.备份GBK版的数据库: 2.用Convertz编码转换软件将备份的数据库文件由GBK转为UTF-8: 3.将转换后的数据库恢复到UTF- ...
- mysql设置字符集gb2312_MySQL字符集 GBK、GB2312、UTF8區別 解決 MYSQL中文亂碼問題
MySQL中涉及的幾個字符集 character-set-server/default-character-set:服務器字符集,默認情況下所采用的. character-set-database:數 ...
- 字符集GBK升级UTF8
在生产环境中,数据库字符集因为各种原因需要升级,比如为了支持汉字,从latin1字符集升级到GBK,后面为了支持多个语言文字,需要将GBK升级到UTF8等.迁移过程网上有很多,我今天主要想讲下字符集转 ...
- 深入理解字符,字符集,gbk,utf8
原创博客地址:深入理解字符,字符集,gbk,utf8 字符,字符集,字符编码概念 字节 1 字节(Byte)是计算机中数据存储的基本单元,一字节等于一个8位的比特,计算机中的所有数据,不论是保存在磁盘 ...
- EBCDIC 与 GBK 的字符编码及其转换(转)
概览 有些用户在使用 AIX 时在字符编码方面遇到一些困惑,请看下面的场景: 1,用户用从 AIX 利用 FTP 客户端登录上 IBM i,切换到某个 Library/File,然后 get 其中的某 ...
最新文章
- 最新!2021 中国内地大学 ESI 排名出炉
- 文巾解题 56. 合并区间
- html5列表标签代码,HTML5列表标签和表格标签(示例代码)
- Angular实现图片点击缩放组件
- LeetCode算法入门- String to Integer (atoi)-day7
- 异域linux内核漏洞,Linux内核再现漏洞!这次11年后才发现
- ServletConfig讲解
- 军用装备温湿度循环测试,温湿度环境可靠性实验室GJB150A
- 在html页面中加入矢量图,在html中引用矢量图
- 人类首次捕获到反物质 500克能量可超过氢弹
- zimbra更换服务器域名
- 前端面试题之 对Promise的理解
- CSS:字体样式(字体系列、大小、加粗、风格、变形等)
- 网络存储服务器接显示器,Unraid下,单核显IGPU实现win10外接显示屏,显卡成功驱动...
- 万字详解大数据平台异地多机房架构实践
- KF、EKF、ESKF的区别与联系
- 内网渗透-window权限维持
- 【太虚AR_v0.1】使用教程 | 图像识别(多目标)
- 号卡推广管理系统源码 手机卡流量卡推广网站源码 带后台版本
- 小米手机 开发app python_python之小米应用商店爬虫
热门文章
- js日期减一个月_正正正国庆!折上再减!三亚/香格里拉/稻城/拈花湾,最低499元…...
- 基于STM32F103+涂鸦三明治的宠物自动喂食器
- 【Spring Boot】——集成JSON工具
- html5超级玛丽小游戏
- 地图标识符号大全_起名字大全男孩 男孩名字,起名字大全男孩
- 读书项目:ePub标准介绍
- CENTOS 7 完全硬盘安装及使用 1
- PUF论文整理2:2021_A_Novel_Modeling-Attack_Resilient_Arbiter-PUF_Design
- java的副语言_公共表达中,悄悄影响你的“副语言”
- C++ 中调用 Jscript 的函数