背景
故事要从一起乱码事件开始。 有用户发现插入的中文数据出现乱码,不知道是什么原因造成的。 用户希望了解问题的根本原因,并确保系统配置正确,以免以后出现乱码。 用户数据表中存储中文数据的列字符集为utf8。 分析审计日志后发现,在插入或更新数据时,数据库连接使用的字符集(集名称;)出现乱码数据。
又出现乱码
• use test;• drop table if t1;• table t1 ( (10), (100)) =utf8;• 设置名称 ;• into t1 ('', '王');• 设置名称 utf8;• into t1 ( 'utf8', '王');• 设置名称;• * 来自 t1;• , hex() 来自 t1;• 设置名称 utf8;• * 来自 t1;• , hex() 来自 t1;
乱码复现 乱码分析 MySQL字符集转换时序
当一条SQL语句进入MySQL执行并返回最终结果时,可能会经历两次字符集转换。 A。 MySQL收到SQL语句后,会进行字符集转换。 如果连接的字符集和列的字符集不同,则会执行转换。 b. MySQL在发送结果之前也会进行字符集转换。 如果连接的字符集和列的字符集不同,则会执行转换。
字符集转换分析
王的utf8编码是E7 8E 8B
情况1
1.1插入Set名称;•接收E7 8E 8B为(客户端直接使用utf8的编码,为什么?)•将编码转换为C3 A7 C5 BD E2 80 B9为utf8,并存储在记录中——这个转换导致1.2 查询集名称乱码; • 返回查询结果,编码转换为E7 8E 8B 为 • 界面显示正确的汉字。 1.3 查询集名称utf8; • 查询结果未经编码转换返回 C3 A7 C5 BD E2 80 B9 as utf8 • 界面显示乱码,无法识别utf8字符。
案例#2
2.1 插入集合名称 utf8;• 接收 E7 8E 8B 作为 utf8• 无需将 E7 8E 8B 转换为 utf8,存储在记录中 2.2 查询集合名称 utf8;• 返回查询结果,无需将 E7 8E 8B 转换为 utf8 • 界面显示正确汉字 2.3 查询集名称;• 返回查询结果,编码转换为3F as——编码信息丢失! ! ! • 界面显示为? ,可以理解为乱码
从我个人的理解来看,数据库乱码是指根据列的字符集属性解析磁盘页面中存储的列的内容时,无法显示正确的字符。 情况1是数据库乱码,情况2则不是。
乱码识别
那么如何识别乱码呢? 当然,最直观的就是从用户界面的显示上一眼就能看出代码是否乱码。 那么有没有办法通过程序自动识别乱码呢? 对于这种中文乱码的情况,可以使用以下方法来识别。
转换为gbk,如果出现3F,则表示乱码。 , HEX(cast((, CHAR SET gbk) as )) from t1;
•(插入)C3 A7 C5 BD E2 80 B9 为utf8,编码转换3F 3F 3F 为gbk — 编码信息丢失! ! ! • (utf8 )E7 8E 8B as utf8,编码转换 CD F5• 不进行编码转换返回
乱码识别及乱码修复
乱码编码能否转换(可逆)?• HEX(CAST(((X'', CHAR SET utf8), CHAR CHA SET ) AS ));• E7 8E 8B• 转换成功!
• t1 set = CAST(CAST((, CHAR SET ) AS ) AS CHAR SET utf8) where ='';• 将 C3 A7 C5 BD E2 80 B9 记录为 utf8• 第一次转换为 E7 8E 8B 作为 。 —这已恢复为正确的utf8编码,但字符集属性为 • 第二次转换为E7 8E 8B as —用作过渡 • 第三次转换为E7 8E 8B as utf8 —编码恢复正常!
字符集和字符集编码
是一个字符集
编码 • UTF-8 使用 1-3 个字节对字符集进行编码,兼容 ASCII 码,但不包含 emoji 表情包,对应 MySQL 字符集 utf8 • UTF-16 使用 1-2 个 16 位进行编码字符集,通常称为宽(UTF-16就是at(和中)。) • UTF-32使用4个字节来编码字符集,也就是大家日常所说的utf8,对应MySQL字符集严格意义上的设置说,MySQL所说的字符集实际上是指字符集编码。
字符集转换原理
MySQL总共有几十种字符集。 这么多字符集之间如何转换? • 所有转换均通过UTF-16 字符集编码执行! ! ! • 参见函数() • 第一步是将源字符集转换为ucs2:c mb_wc • 第二步将ucs2 转换为目标字符集:b wc_mb
注:大多数情况下UTF-16和ucs2可以理解为等价的。 具体差异请参考UCS-2及其to(UTF-16)[1]
字符集相关变量
MySQL中有8个关于字符集的全局变量。 详细信息请参考官方文档。
参考链接
[1]
UCS-2 及其 (UTF-16):
[2]
MySQL 集 & :
[3]
MySQL字符集知识:
好了,今天的主题就讲到这里吧,不管如何,能帮到你我就很开心了,如果您觉得这篇文章写得不错,欢迎点赞和分享给身边的朋友。