文章目录
在数据库操作中,偶尔我们可能会碰到一些乱码问题,有时候是在进行数据写入时出现的乱码无法正常写入数据,有时候是数据查询的时候发现看到很多乱码显示,这些其实都是字符集格式导致的问题。面对乱码的问题,我们该如何解决处理这个问题?
一、常见字符集格式乱码问题
1.1 写入乱码
当进行数据写入时,字符集格式转换无法与库表内部字符集格式兼容,出现以下报错:
1.2 查询乱码
当进行数据查询时,字符集格式转换无法无损转换,导致我们查询出来的数据无法正常显示,出现“??”的乱码显示:
二、数据库文本写入/查询乱码原因
数据库查询/写入出现的乱码问题,其实归根结底都是字符集格式转换导致的问题,由此我们可以先来了解下,常见的操作系统以及数据库中的字符集格式、以及客户端与MySQL服务端究竟是如何进行字符集格式转换的。
2.1 常见字符集格式设置
1、操作系统
# echo $LANG
zh_CN.UTF-8
2、数据库
mysql> show variables like 'character_set%';
character_set_client # 客户端字符集,当客户端发起连接,使用客户端请求的字符集格式设置此变量的会话值。
character_set_connection # 客户端连接字符集
character_set_database # 数据库字符集
character_set_filesystem # 文件系统字符集,使用LOAD DATA或者SELECT ... INTO OUTFILE时采用的默认字符集格式
character_set_results # 客户端返回结果字符集
character_set_server # 服务器默认字符集
character_set_system # 服务器用于存储标识符的字符集,该值始终为utf8。
2.2 MySQL字符集转换过程
1、MySQL Client发起请求到MySQL Server,请求数据的字符集格式由character_set_client转换为character_set_connection
2、进入到MySQL Server内部,请求数据的字符集由character_set_connection转换为内部操作字符集,内部字符集格式选择优先级如下:
1)优先使用每个字段定义的字符集格式
2)若字段没有明确标识字符集格式,使用建表定义的字符集格式
3)若表没有明确标识字符集格式,使用数据库定义的字符集格式
4)若数据库没有明确标识字符集格式,使用character_set_server定义的字符集格式
3、请求数据内部处理完毕后,由以上内部字符集中优先使用的字符集格式转换为character_set_results返回给客户端
2.3 字符集格式乱码原因
在客户端与服务端的交互中,出现了多次字符集格式的转换,主要为:
charcter_set_client --> character_setconection
character_set_connection --> 内部操作字符集
内部操作字符集 --> character_set_result
character_set_result --> character_set_client
当字符集格式之间的转乱有些是无法进行无损转换的,当字符集格式无法无损转换就会导致我们无论是写入还是查询,出现一些乱码现象。
三、如何解决处理字符集格式乱码
1、在MySQL数据库中对库表结构设计时,根据业务需求创建合适的字符集格式,尽量保证库、表、字段中所有的字符集格式统一
2、业务代码层,在创建连接数据库的url连接串时,使用正确的字符集格式编码,尽量保证代码层使用的字符集格式与charcter_set_client一致
3、合理的设置数据库charcter_set_client 、character_setconection、character_set_result,保证该三者一致
4、当字符集格式已经转换出现乱码时:
1)检查数据库内部库/表/字段字符集格式,若内部字符集转换本身无法满足业务需求,需调整具体表的字符集格式处理,如utf8字符集格式无法显示emoji表情,需要调整为utf8mb4处理。
2)检查代码层数据库连接串字符集格式设置与aracter_setconection、character_set_result是否保持一致,若连接串字符串格式设置错误,修改业务代码处理
3)可在代码层对应的乱码业务逻辑中,显式地使用 “set names ${character}” 来保证charcter_set_client 、character_setconection、character_set_result这三者字符集一致