MySQL 异常 UTF-8 字符的处理

ETL流程中,我们会将Hive中的数据导入MySQL——先用Hive命令行将数据保存为文本文件,然后用MySQL的LOAD DATA语句进行加载。最近有一张表在加载到MySQL时会报以下错误:

Incorrect string value: '\xF0\x9D\x8C\x86' for column ...

经查,这个字段中保存的是用户聊天记录,因此会有一些表情符号。这些符号在UTF-8编码下需要使用4个字节来记录,而MySQL中的utf8编码只支持3个字节,因此无法导入。

根据UTF-8的编码规范,3个字节支持的Unicode字符范围是U+0000–U+FFFF,因此可以在Hive中对数据做一下清洗:

SELECT REGEXP_REPLACE(content, '[^\\u0000-\\uFFFF]', '') FROM ...

这样就能排除那些需要使用3个以上字节来记录的字符了,从而成功导入MySQL。

以下是一些详细说明和参考资料。

Unicode字符集和UTF编码

Unicode字符集是一种将全球所有文字都囊括在内的字符集,从而实现跨语言、跨平台的文字信息交换。它由基本多语平面(BMP)和多个扩展平面(non-BMP)组成。前者的编码范围是U+0000-U+FFFF,包括了绝大多数现代语言文字,因此最为常用。

UTF则是一种编码格式,负责将Unicode字符对应的编号转换为计算机可以识别的二进制数据,进行保存和读取。

比如,磁盘上记录了以下二进制数据:

1101000 1100101 1101100 1101100 1101111

读取它的程序知道这是以UTF-8编码保存的字符串,因此将其解析为以下编号:

104 101 108 108 111 

又因为UTF-8编码对应的字符集是Unicode,所以上面这五个编号对应的字符便是“hello”。

很多人会将Unicode和UTF混淆,但两者并不具可比性,它们完成的功能是不同的。

UTF-8编码

UTF编码家族也有很多成员,其中UTF-8最为常用。它是一种变长的编码格式,对于ASCII码中的字符使用1个字节进行编码,对于中文等则使用3个字节。这样做的优点是在存储西方语言文字时不会造成空间浪费,不像UTF-16和UTF-32,分别使用两个字节和四个字节对所有字符进行编码。

UTF-8编码的字节数上限并不是3个。对于U+0000-U+FFFF范围内的字符,使用3个字节可以表示完全;对于non-BMP中的字符,则会使用4-6个字节来表示。同样,UTF-16编码也会使用四个字节来表示non-BMP中的字符。

MySQL的UTF-8编码

根据MySQL的官方文档,它的UTF-8编码支持是不完全的,最多使用3个字符,这也是导入数据时报错的原因。

MySQL5.5开始支持utf8mb4编码,至多使用4个字节,因此能包含到non-BMP字符。只是我们的MySQL版本仍是5.1,因此选择丢弃这些字符。

参考资料

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: 在 MySQL 中,如果数据库的字符集设置为 UTF-8,但表字段的字符集设置为 GBK,会导致以下影响: 1. 在存储数据时会出现乱码,因为 MySQL 会将数据从 UTF-8 编码转换为 GBK 编码,但 GBK 编码无法正确表示 UTF-8 编码的所有字符,所以会出现乱码。 2. 在查询数据时会出现问题,因为 MySQL 会将查询结果从 GBK 编码转换为 UTF-8 编码,但 GBK 编码无法正确表示 UTF-8 编码的所有字符,所以会出现问题。 建议将数据库和表字段的字符集都设置为 UTF-8,这样可以避免上述问题。 ### 回答2: 当MySQL中数据库的字符集为utf-8,但表字段中字符集为gbk时,会出现以下影响: 1. 存储问题:由于utf-8是一种多字节字符集,而gbk是一种双字节字符集,所以当在utf-8数据库中存储gbk字符时,会导致一个gbk字符占用更多的存储空间,可能引起数据浪费。 2. 编码问题:当utf-8数据库中的表字段字符集为gbk时,会导致编码不一致。当从应用程序中插入或读取数据时,可能会出现字符编码乱码或无法正常显示的情况,特别是在处理特殊字符时更容易出现问题。 3. 排序和比较问题:utf-8和gbk字符集具有不同的排序规则和比较方式。如果在不同字符集之间比较和排序数据,可能导致错误的结果。 4. 查询问题:如果在utf-8数据库表中的gbk字段上进行查询,可能会导致查询结果不准确或无法正常检索到数据。 综上所述,当MySQL中数据库字符集为utf-8,但表字段中字符集为gbk时,可能会导致存储、编码、排序和查询等方面的问题。为避免这些问题,建议一致地设置字符集,即数据库和表字段应该采用相同的字符集,例如utf-8字符集。 ### 回答3: 当MySQL数据库的字符集为UTF-8(或UTF-8编码的别名)时,它可以存储包括汉字在内的各种国际字符集,并且支持多种语言的数据存储与查询。而表字段中字符集为GBK,则表示该字段中的数据只能使用GBK字符集进行存储和检索。 对于数据库字符集为UTF-8但表字段中字符集为GBK的情况,会产生以下影响: 1. 数据存储:当使用UTF-8字符集插入数据到字段中时,MySQL会首先将UTF-8字符集转换为GBK字符集,然后再存储到表字段中。这可能导致一些特殊字符无法正确保存或显示。 2. 字符编码转换:如果从数据库中查询数据并将其显示在页面上时,数据库会将存储在GBK字符集中的数据转换为UTF-8字符集进行显示。这种字符编码转换可能会导致数据显示异常或乱码。 3. 查询效率:由于MySQL需要进行字符集转换,从UTF-8到GBK或从GBK到UTF-8的转换会消耗一定的计算资源和时间。在大数据量或复杂查询的情况下,这些转换可能会降低查询效率。 因此,建议在设计数据库时,数据库的字符集和表字段的字符集应保持一致,以避免字符集转换引起的问题。如果需要存储和处理多语言数据,推荐使用UTF-8字符集,它能够更好地支持各种语言和字符集。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值