源码网商城,靠谱的源码在线交易网站 我的订单 购物车 帮助

源码网商城

mysql数据校验过程中的字符集问题处理

  • 时间:2022-08-04 04:39 编辑: 来源: 阅读:
  • 扫一扫,手机访问
摘要:mysql数据校验过程中的字符集问题处理
场景: 主库DB:utf8字符集 备库DB:gbk字符集 需求: 校验主备数据是否一致,并且修复 校验过程: 设置主库连接为utf8,设置备库连接为gbk,分别进行查询,将返回的的结果集按记录逐字段比较。 显示结果: 原本相同的汉字字符,数据校验认为不一致。 原因分析: 对于主库而已,由于建立连接的字符集为UTF8,则返回的汉字字符编码为UTF8格式;对于备库而言则是GBK格式,而程序中通过字符串比较函数strcasecmp进行比较,显然不同的字符集编码,相同的字符有不同的二进制,因此结果肯定不会相等。 进一步分析: 那么对于这种情况,建立连接应该采用哪种字符集呢?GBK or UTF8。其实选择任何一种字符集都是OK的,只要是访问主库和备库的字符集保持一致即可,唯一的区别在于,若选择的字符集与客户端的字符集不一致,可能导致无法正常显示字符,即字符显示为乱码。 我们以客户端的字符集为例,详细说说三种情况:【这里的客户端可以认为是SecureCRT】 备注:绿色框代表DB字符集,黄色框代表连接字符集,橙色框代表客户端 [b]第一种情况:[/b] [img]http://files.jb51.net/file_images/article/201405/2014513155817288.png?2014413155913[/img] 就是上述的情况,主库返回字符的GBK编码,备库返回字符的UTF8编码,因此进行字段比对,则会出现误差。 [b]第二种情况:[/b] [img]http://files.jb51.net/file_images/article/201405/2014513160422771.png?201441316444[/img] 访问主库的连接不变,备库连接由UTF8变为GBK,因此进行返回时,数据库会将DB的字符集转为GBK返回给客户端,那么对于客户端而已,相同字符都是通过GBK编码表示,因此二进制相等,校验结果正确。 [b]第三种情况:[/b] [img]http://files.jb51.net/file_images/article/201405/2014513160544045.png?20144131661[/img]    访问主库和备库的连接都是UTF8,因此对于主库而已,返回给客户端的字符编码由GBK转为UTF8,此时主库和备库都是UTF8编码,校验结果正确。但由于客户端实质是GBK编码方式显示,因此返回的汉字字符都是乱码,但不影响校验结果的正确性。 修复:       既然选择与主备库任一一个相同的字符集去访问,都不会影响校验结果的正确性,那么影响修复呢?由于UTF8的编码范围比GBK编码范围要大,因此若采用GBK连接访问UTF8编码DB,有可能出现部分字符GBK不能表示的情况。 我们拿第二种情况说明,此时主库为GBK,备库为UTF8,使用GBK访问UTF8。假设存在UTF8转为GBK过程中部分字符丢失,这时候主备库肯定是不一致的,因为存在部分字符GBK无法表示。 假设修复语句如下: Update  t set c1=master_value  where  c1=slave_value  and id=? 其中t表示表名,id是主键表示某一行,master_value为主库c1列的值,slave_value为备库c1列的值。此时,slave_value由于UTF8转为GBK已经丢失,因此语句执行最终影响0行记录,无法修复。   结论: 客户端访问两个不同字符集库进行数据校验时,连接采用表示范围更大的字符集。比如我们常用的字符集表示范围如下: Latin<gb2312<gbk<utf8   附:mysql客户端与服务器通信时字符集编码转换流程 相关参数: – character_set_client:客户端来源数据使用的字符集 – character_set_connection:连接层字符集 – character_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; 附图: [img]http://files.jb51.net/file_images/article/201405/2014513160722096.png?201441316742[/img]
  • 全部评论(0)
联系客服
客服电话:
400-000-3129
微信版

扫一扫进微信版
返回顶部