侯体宗的博客
  • 首页
  • Hyperf版
  • beego仿版
  • 人生(杂谈)
  • 技术
  • 关于我
  • 更多分类
    • 文件下载
    • 文字修仙
    • 中国象棋ai
    • 群聊
    • 九宫格抽奖
    • 拼图
    • 消消乐
    • 相册

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

数据库  /  管理员 发布于 6年前   133

场景:
主库DB:utf8字符集
备库DB:gbk字符集

需求:
校验主备数据是否一致,并且修复

校验过程:
设置主库连接为utf8,设置备库连接为gbk,分别进行查询,将返回的的结果集按记录逐字段比较。

显示结果:
原本相同的汉字字符,数据校验认为不一致。

原因分析:
对于主库而已,由于建立连接的字符集为UTF8,则返回的汉字字符编码为UTF8格式;对于备库而言则是GBK格式,而程序中通过字符串比较函数strcasecmp进行比较,显然不同的字符集编码,相同的字符有不同的二进制,因此结果肯定不会相等。

进一步分析:
那么对于这种情况,建立连接应该采用哪种字符集呢?GBK or UTF8。其实选择任何一种字符集都是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=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客户端与服务器通信时字符集编码转换流程

相关参数:

C character_set_client:客户端来源数据使用的字符集

C character_set_connection:连接层字符集

C character_set_results:查询结果字符集

C character_set_database:当前选中数据库的默认字符集

C 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中SELECT+UPDATE处理并发更新问题解决方案分享
    下一条:
    mysql的3种分表方案
  • 昵称:

    邮箱:

    0条评论 (评论内容有缓存机制,请悉知!)
    最新最热
    • 分类目录
    • 人生(杂谈)
    • 技术
    • linux
    • Java
    • php
    • 框架(架构)
    • 前端
    • ThinkPHP
    • 数据库
    • 微信(小程序)
    • Laravel
    • Redis
    • Docker
    • Go
    • swoole
    • Windows
    • Python
    • 苹果(mac/ios)
    • 相关文章
    • 分库分表的目的、优缺点及具体实现方式介绍(0个评论)
    • DevDB - 在 VS 代码中直接访问数据库(0个评论)
    • 在ubuntu系统中实现mysql数据存储目录迁移流程步骤(0个评论)
    • 在mysql中使用存储过程批量新增测试数据流程步骤(0个评论)
    • php+mysql数据库批量根据条件快速更新、连表更新sql实现(0个评论)
    • 近期文章
    • 在go中实现一个常用的先进先出的缓存淘汰算法示例代码(0个评论)
    • 在go+gin中使用"github.com/skip2/go-qrcode"实现url转二维码功能(0个评论)
    • 在go语言中使用api.geonames.org接口实现根据国际邮政编码获取地址信息功能(1个评论)
    • 在go语言中使用github.com/signintech/gopdf实现生成pdf分页文件功能(0个评论)
    • gmail发邮件报错:534 5.7.9 Application-specific password required...解决方案(0个评论)
    • 欧盟关于强迫劳动的规定的官方举报渠道及官方举报网站(0个评论)
    • 在go语言中使用github.com/signintech/gopdf实现生成pdf文件功能(0个评论)
    • Laravel从Accel获得5700万美元A轮融资(0个评论)
    • 在go + gin中gorm实现指定搜索/区间搜索分页列表功能接口实例(0个评论)
    • 在go语言中实现IP/CIDR的ip和netmask互转及IP段形式互转及ip是否存在IP/CIDR(0个评论)
    • 近期评论
    • 122 在

      学历:一种延缓就业设计,生活需求下的权衡之选中评论 工作几年后,报名考研了,到现在还没认真学习备考,迷茫中。作为一名北漂互联网打工人..
    • 123 在

      Clash for Windows作者删库跑路了,github已404中评论 按理说只要你在国内,所有的流量进出都在监控范围内,不管你怎么隐藏也没用,想搞你分..
    • 原梓番博客 在

      在Laravel框架中使用模型Model分表最简单的方法中评论 好久好久都没看友情链接申请了,今天刚看,已经添加。..
    • 博主 在

      佛跳墙vpn软件不会用?上不了网?佛跳墙vpn常见问题以及解决办法中评论 @1111老铁这个不行了,可以看看近期评论的其他文章..
    • 1111 在

      佛跳墙vpn软件不会用?上不了网?佛跳墙vpn常见问题以及解决办法中评论 网站不能打开,博主百忙中能否发个APP下载链接,佛跳墙或极光..
    • 2017-06
    • 2017-08
    • 2017-09
    • 2017-10
    • 2017-11
    • 2018-01
    • 2018-05
    • 2018-10
    • 2018-11
    • 2020-02
    • 2020-03
    • 2020-04
    • 2020-05
    • 2020-06
    • 2020-07
    • 2020-08
    • 2020-09
    • 2021-02
    • 2021-04
    • 2021-07
    • 2021-08
    • 2021-11
    • 2021-12
    • 2022-02
    • 2022-03
    • 2022-05
    • 2022-06
    • 2022-07
    • 2022-08
    • 2022-09
    • 2022-10
    • 2022-11
    • 2022-12
    • 2023-01
    • 2023-03
    • 2023-04
    • 2023-05
    • 2023-07
    • 2023-08
    • 2023-10
    • 2023-11
    • 2023-12
    • 2024-01
    • 2024-03
    Top

    Copyright·© 2019 侯体宗版权所有· 粤ICP备20027696号 PHP交流群

    侯体宗的博客