伍佰目录 短网址
  当前位置:海洋目录网 » 站长资讯 » 站长资讯 » 文章详细 订阅RssFeed

这么神气的”乱"码字符无法导入数据库--怎么弄?

来源:本站原创 浏览:125次 时间:2022-09-19

    相信大家在使用mysql的时候,会感叹mysql非常灵活的字符集设置,可以将字符集在多个层次上设置,如server,客户端,数据库,表,以及字段上设置字符集。而往往越是灵活,越容易搞混乱,也更容易遇到各种字符集的问题。 我们可以通过设置客户端字符集,或者使用命令set names xxx等等,来处理字符集的问题。也通常认为,utf8可以搞定任何字符,容纳任何字符。如果utf8都搞不定,utf8mb4肯定可以。

          本次对字符集的源码学习,来自于一次扎心的数据导入:有一部分表从db2 通过exp 命令,导出成文本文件,文本文件总共180G ,然后再通过load 命令导入到mysql.期间经历列分隔符被干扰的情况, 处理之后,发现行分割符也有被字符类型的列中的数据干扰。  将这些情况都处理之后,然后信心满满地认为,这次应该可以成功将所有数据导入了吧 。 结果,结果还是挺令人悲催,两个超级大表依然出现失败。

        报错信息如图:




        从db2导出设置为utf8, mysql的表也设置为utf8, 但又出现这样的幺蛾子,怎么整 ?

          这肯定是跨平台的问题? 或者db2utf8跟mysql utf8的范围不一样。 xxx,表面上&嘴上没有反驳,但心里嘀咕,utf8不是统一的字符集莫? 哪里还分db2跟oracle,或者mysql.


          没有办法,为了这个“服”字(让自己服),只能撸代码来找真正的答案。慢慢地寻根问底,找到了处理/验证utf8字符的函数。

          

staticint my_valid_mbcharlen_utf8(const CHARSET_INFO *cs MY_ATTRIBUTE((unused)),                            const uchar *s, const uchar *e){  uchar c;  if (s >= e)    return MY_CS_TOOSMALL;  c= s[0];  if (c < 0xf0)    return my_valid_mbcharlen_utf8mb3(s, e);#ifdef UNICODE_32BIT  if (c < 0xf8 && sizeof(my_wc_t)*8 >= 32)  {    if (s+4 > e) /* We need 4 characters */      return MY_CS_TOOSMALL4;    if (!(IS_CONTINUATION_BYTE(s[1]) &&          IS_CONTINUATION_BYTE(s[2]) &&          IS_CONTINUATION_BYTE(s[3]) &&          (c >= 0xf1 || s[1] >= 0x90)))      return MY_CS_ILSEQ;    return 4;  }  if (c < 0xfc && sizeof(my_wc_t)*8 >= 32)  {    if (s+5 >e) /* We need 5 characters */      return MY_CS_TOOSMALL5;    if (!(IS_CONTINUATION_BYTE(s[1]) &&          IS_CONTINUATION_BYTE(s[2]) &&          IS_CONTINUATION_BYTE(s[3]) &&          IS_CONTINUATION_BYTE(s[4]) &&          (c >= 0xf9 || s[1] >= 0x88)))      return MY_CS_ILSEQ;    return 5;  }  if (c < 0xfe && sizeof(my_wc_t)*8 >= 32)  {    if ( s+6 >e ) /* We need 6 characters */      return MY_CS_TOOSMALL6;    if (!(IS_CONTINUATION_BYTE(s[1]) &&          IS_CONTINUATION_BYTE(s[2]) &&          IS_CONTINUATION_BYTE(s[3]) &&          IS_CONTINUATION_BYTE(s[4]) &&          IS_CONTINUATION_BYTE(s[5]) &&          (c >= 0xfd || s[1] >= 0x84)))      return MY_CS_ILSEQ;    return 6;  }#endif  return MY_CS_ILSEQ;}


          通过上面的代码段,我们可以看到,当文字的第一个字节小于0xf0时,才调用函数my_valid_mbcharlen_utf8mb3(s, e);进行处理3字节的utf8

(有发现没?所有报错的数据的二进制码都是以f0开头), 否则,如果定义了宏UNICODE_32BIT, 才进入4字节以上(含)字符的处理流程,如果没有定义该宏,则直接返回MY_CI_ILSEQ. 也就是无效的字符。
   那采用utf8mb4是否可以呢? 答案依然是no, 这些字符都被解析成?        再后来,直接修改mysql源码文件中CmakeList.txt文件,将宏UNICODE_32BIT指定,将mysql重新编译,然后重新执行,数据成功insert.      请看这个特殊字符插入成功后的效果。

    目前已经将该case 提交给mysql官方,看看能否得到官方的确认跟反馈,针对这类字符该怎么弄? bug id  88529  ,url https://bugs.mysql.com/bug.php?id=88529


           有兴趣了解这个case,以及最后的处理方式,请关注这个bug更新。


           对了,好像作者较少在文章末尾加入邀请各位读者关注该作者公众号的文字,这次加不加?

           点击原文连接,从mysql官网了解该case的进展。


  推荐站点

  • At-lib分类目录At-lib分类目录

    At-lib网站分类目录汇集全国所有高质量网站,是中国权威的中文网站分类目录,给站长提供免费网址目录提交收录和推荐最新最全的优秀网站大全是名站导航之家

    www.at-lib.cn
  • 中国链接目录中国链接目录

    中国链接目录简称链接目录,是收录优秀网站和淘宝网店的网站分类目录,为您提供优质的网址导航服务,也是网店进行收录推广,站长免费推广网站、加快百度收录、增加友情链接和网站外链的平台。

    www.cnlink.org
  • 35目录网35目录网

    35目录免费收录各类优秀网站,全力打造互动式网站目录,提供网站分类目录检索,关键字搜索功能。欢迎您向35目录推荐、提交优秀网站。

    www.35mulu.com
  • 就要爱网站目录就要爱网站目录

    就要爱网站目录,按主题和类别列出网站。所有提交的网站都经过人工审查,确保质量和无垃圾邮件的结果。

    www.912219.com
  • 伍佰目录伍佰目录

    伍佰网站目录免费收录各类优秀网站,全力打造互动式网站目录,提供网站分类目录检索,关键字搜索功能。欢迎您向伍佰目录推荐、提交优秀网站。

    www.wbwb.net