MySQL运维实战(5.3) MySQL数据乱码的一些情况

作者:俊达

表数据乱码

表数据出现乱码的情况通常是由于数据的真实编码与相关参数不一致引起的,其中包括常见的参数如character_set_client、character_set_results、字段编码以及终端编码等。确保这些参数保持一致,可以有效预防和解决乱码问题。

测试1 - 表中的数据正常,但是character_set_result设置和终端的实际字符集不匹配

终端的字符编码为utf8
在这里插入图片描述

mysql> show variables like '%char%';
+--------------------------+------------------------------------------------------+
| Variable_name            | Value                                                |
+--------------------------+------------------------------------------------------+
| character_set_client     | utf8mb3                                              |
| character_set_connection | utf8mb3                                              |
| character_set_database   | utf8mb4                                              |
| character_set_filesystem | binary                                               |
| character_set_results    | utf8mb3                                              |
| character_set_server     | latin1                                               |
| character_set_system     | utf8mb3                                              |
| character_sets_dir       | /usr/local/Cellar/mysql/8.0.31/share/mysql/charsets/ |
+--------------------------+------------------------------------------------------+
8 rows in set (0.00 sec)

mysql> create table test_charset(a varchar(100)) default charset utf8;
Query OK, 0 rows affected, 1 warning (0.01 sec)

mysql> insert into test_charset values('列列列列列AAA');
Query OK, 1 row affected (0.01 sec)

mysql> select * from test_charset;
+--------------------+
| a                  |
+--------------------+
| 列列列列列AAA      |
+--------------------+
1 row in set (0.00 sec)

将character_set_results设置为gbk,则无法正常显示返回的数据:

mysql> set character_set_results=gbk;
Query OK, 0 rows affected (0.00 sec)

mysql> select *,hex(a) from test_charset;
+---------------+--------------------------------------+
| a             | hex(a)                               |
+---------------+--------------------------------------+
| ����������AAA           | E58897E58897E58897E58897E58897414141 |
+---------------+--------------------------------------+

在另外一个GBK编码的终端下:
在这里插入图片描述

mysql> set character_set_results=gbk;
Query OK, 0 rows affected (0.00 sec)

mysql> select *, hex(a) from test_charset;
+---------------+--------------------------------------+
| a             | hex(a)                               |
+---------------+--------------------------------------+
| 列列列列列AAA | E58897E58897E58897E58897E58897414141 |
+---------------+--------------------------------------+
1 row in set (0.00 sec)



mysql> set character_set_results=utf8;
Query OK, 0 rows affected, 1 warning (0.00 sec)

mysql> select *, hex(a) from test_charset;
+--------------------+--------------------------------------+
| a                  | hex(a)                               |
+--------------------+--------------------------------------+
| 鍒楀垪鍒楀垪鍒桝AA | E58897E58897E58897E58897E58897414141 |
+--------------------+--------------------------------------+
1 row in set (0.01 sec)

上面这几个例子中,数据库中存储的数据没有问题(使用hex函数查看真实的数据,和字符的字符集(UTF8)编码一致),但是因为客户端的字符编码设置不对,导致无法正常查看字符。

测试2 - character_set_client和终端的字符集不匹配

2.1 utf8终端,character_set_client设置为gbk,写入数据
create table test_charset2(a varchar(100), b varchar(100)) default charset utf8;

-- utf8终端
mysql> set character_set_client='gbk';
Query OK, 0 rows affected (0.00 sec)

mysql> insert into test_charset2 values('term: utf8, charset client: gbk', '列列列列列AAA');
Query OK, 1 row affected (0.00 sec)


mysql> select *, hex(b) from test_charset2;
+---------------------------------+----------------------------+------------------------------------------------------+
| a                               | b                          | hex(b)                                               |
+---------------------------------+----------------------------+------------------------------------------------------+
| term: utf8, charset client: gbk | 鍒楀垪鍒楀垪鍒桝AA         | E98D92E6A580E59EAAE98D92E6A580E59EAAE98D92E6A19D4141 |
+---------------------------------+----------------------------+------------------------------------------------------+
1 row in set (0.00 sec)

汉字“列”的utf8编码应该是E58897,但是表中实际存储的数据不对。

>>> u"列".encode('utf8')
'\xe5\x88\x97'

测试2.1中,由于character_set_client和实际的数据的字符集编码不匹配,导致表里存储的数据本身就是有问题的(汉字“列”的utf8编码为e58897)。
使用python模拟这个过程:

-- 本来是utf8编码的数据,使用gbk编码来解码,然后再以utf8(表的字符集)方式编码
>>> u"列列列列列AAA".encode('utf8').decode('gbk').encode('utf8')
'\xe9\x8d\x92\xe6\xa5\x80\xe5\x9e\xaa\xe9\x8d\x92\xe6\xa5\x80\xe5\x9e\xaa\xe9\x8d\x92\xe6\xa1\x9dAA'

>>> print u"列列列列列AAA".encode('utf8').decode('gbk').encode('utf8')
鍒楀垪鍒楀垪鍒桝AA
2.2 gbk终端,character_set_client设置为utf8,写入数据
-- gbk终端

mysql> set character_set_client='utf8';
Query OK, 0 rows affected, 1 warning (0.00 sec)

mysql> insert into test_charset2 values('term: gbk, charset client: utf8', '列列列列列AAA');
Query OK, 1 row affected, 1 warning (0.01 sec)

mysql> show warnings;
+---------+------+-------------------------------------------------------------------------+
| Level   | Code | Message                                                                 |
+---------+------+-------------------------------------------------------------------------+
| Warning | 1300 | Cannot convert string '\xC1\xD0\xC1\xD0\xC1\xD0...' from utf8mb3 to gbk |
+---------+------+-------------------------------------------------------------------------+
1 row in set (0.00 sec)


mysql> select *, hex(b) from test_charset2;
+---------------------------------+--------------------+------------------------------------------------------+
| a                               | b                  | hex(b)                                               |
+---------------------------------+--------------------+------------------------------------------------------+
| term: utf8, charset client: gbk | 鍒楀垪鍒楀垪鍒桝AA | E98D92E6A580E59EAAE98D92E6A580E59EAAE98D92E6A19D4141 |
| term: gbk, charset client: utf8 | ??????????AAA      | 3F3F3F3F3F3F3F3F3F3F414141                           |
+---------------------------------+--------------------+------------------------------------------------------+
2 rows in set (0.00 sec)

原因解析
本来时gbk方式编码的数据,使用utf8编码无法解码,使用替换字符(3F) 替换无法解码的数据。

2.3 utf8终端,character_set_results设置为gbk

如果我们将错就错,在utf8终端上,将character_set_results设置为gbk。
查询返回看起来正常的数据:

-- utf8编码的终端

mysql> set character_set_results=gbk;
Query OK, 0 rows affected (0.00 sec)

mysql> select *, hex(b) from test_charset2;
+---------------------------------+--------------------+------------------------------------------------------+
| a                               | b                  | hex(b)                                               |
+---------------------------------+--------------------+------------------------------------------------------+
| term: utf8, charset client: gbk | 列列列列列AAA      | E98D92E6A580E59EAAE98D92E6A580E59EAAE98D92E6A19D4141 |
| term: gbk, charset client: utf8 | ??????????AAA      | 3F3F3F3F3F3F3F3F3F3F414141                           |
+---------------------------------+--------------------+------------------------------------------------------+
2 rows in set (0.00 sec)

原因解析

数据库中实际存储的数据:
>>> u"列列列列列AAA".encode('utf8').decode('gbk').encode('utf8')
'\xe9\x8d\x92\xe6\xa5\x80\xe5\x9e\xaa\xe9\x8d\x92\xe6\xa5\x80\xe5\x9e\xaa\xe9\x8d\x92\xe6\xa1\x9dAA'

-- character_set_results 设置为gbk,则mysql以gbk编码返回数据,
>>> u"列列列列列AAA".encode('utf8').decode('gbk').encode('gbk')
'\xe5\x88\x97\xe5\x88\x97\xe5\x88\x97\xe5\x88\x97\xe5\x88\x97AAA'

-- 由于终端字符集为utf8,以utf8编码解释返回的数据
>>> u"列列列列列AAA".encode('utf8').decode('gbk').encode('gbk').decode('utf8')
u'\u5217\u5217\u5217\u5217\u5217AAA'

u5217就是汉字“列“的unicode编码
2.4 gbk终端,character_set_results设置为utf8

在gbk终端上,将character_set_results设置为utf8:

-- gbk编码的终端

mysql> set character_set_results=utf8;
Query OK, 0 rows affected, 1 warning (0.00 sec)

mysql> select *, hex(b) from test_charset2;
+---------------------------------+----------------------------+------------------------------------------------------+
| a                               | b                          | hex(b)                                               |
+---------------------------------+----------------------------+------------------------------------------------------+
| term: utf8, charset client: gbk | 閸掓鍨崚妤鍨崚妗滱A | E98D92E6A580E59EAAE98D92E6A580E59EAAE98D92E6A19D4141 |
| term: gbk, charset client: utf8 | ??????????AAA              | 3F3F3F3F3F3F3F3F3F3F414141                           |
+---------------------------------+----------------------------+------------------------------------------------------+
2 rows in set (0.00 sec)

原因解析

数据库中实际存储的数据:
>>> u"列列列列列AAA".encode('utf8').decode('gbk').encode('utf8')
'\xe9\x8d\x92\xe6\xa5\x80\xe5\x9e\xaa\xe9\x8d\x92\xe6\xa5\x80\xe5\x9e\xaa\xe9\x8d\x92\xe6\xa1\x9dAA'

-- character_set_results 设置为utf8,则mysql以utf8编码返回数据,
>>> u"列列列列列AAA".encode('utf8').decode('gbk').encode('utf8')
'\xe9\x8d\x92\xe6\xa5\x80\xe5\x9e\xaa\xe9\x8d\x92\xe6\xa5\x80\xe5\x9e\xaa\xe9\x8d\x92\xe6\xa1\x9dAA'

-- 由于终端字符集为gbk,以gbk编码解释返回的数据。
>>> u"列列列列列AAA".encode('utf8').decode('gbk').encode('utf8').decode('gbk')
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
UnicodeDecodeError: 'gbk' codec can't decode bytes in position 4-5: illegal multibyte sequence

-- 加上error='replace'
>>> u"列列列列列AAA".encode('utf8').decode('gbk').encode('utf8').decode('gbk', errors='replace')
u'\u95b8\u6393\ufffd\u9368\ufffd\u5d1a\u59a4\ufffd\u7059\u95b8\u6393\ufffdAA'

>>> print u"列列列列列AAA".encode('utf8').decode('gbk').encode('utf8').decode('gbk', errors='replace')
閸掓�鍨�崚妤�灙閸掓�AA


-- 使gb18030,
>>> u"列列列列列AAA".encode('utf8').decode('gbk').encode('utf8').decode('gb18030', errors='replace')
u'\u95b8\u6393\ue685\u9368\ue048\u5d1a\u59a4\ufffd\u7059\u95b8\u6393\ue522AA'

>>> print u"列列列列列AAA".encode('utf8').decode('gbk').encode('utf8').decode('gb18030', errors='replace')
閸掓鍨崚妤�灙閸掓AA

-- 上面的数据和mysql终端显示的数据(閸掓鍨崚妤鍨崚妗滱A )有一些差异。原因可能是他们对gbk无法解码的数据处理方式有差异。

总结

当客户端字符编码方式和MySQL参数character_set_client、character_set_results设置不匹配时,容易产生乱码。有的时候,数据库存储的数据没有问题,但是客户端编码设置不对,导致看上去有乱码,这种情况下只需要将客户端编码设置正确,就可以了。有的时候,存储到数据库的数据就不对了,甚至原来的数据无法编码,会被“?”等替换字符替换,这时可能就无法得到原先的数据了。

更多技术信息请查看云掣官网https://yunche.pro/?t=yrgw

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/370146.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

【Web】CVE-2021-22448 Log4j RCE漏洞学习

目录 复现流程 漏洞原理 复现流程 启动HTTP->启动LDAP->执行Log4j vps起个http服务,放好Exploit.class这个恶意字节码 LDAPRefServer作为恶意LDAP服务器 import java.net.InetAddress; import java.net.MalformedURLException; import java.net.URL; import javax.ne…

C++ 动态规划 线性DP 最长共同子序列

给定两个长度分别为 N 和 M 的字符串 A 和 B &#xff0c;求既是 A 的子序列又是 B 的子序列的字符串长度最长是多少。 输入格式 第一行包含两个整数 N 和 M 。 第二行包含一个长度为 N 的字符串&#xff0c;表示字符串 A 。 第三行包含一个长度为 M 的字符串&#xff0c;表…

程序员可以考取哪些证书更有用

IT行业有哪些证书 IT行业有许多证书可以考取&#xff0c;以下是一些主要的和有价值的证书相关信息&#xff1a; IT行业常用证书一览表 认证机构认证领域证书名称能力概述思科认证网络工程师CCNA、CCNP和CCIE等不同级别思科公司颁发的网络开发运维架构能力微软认证系统开发工程…

爬虫-网络空间微博信息管理系统的设计与实现-计算机毕业设计源码85633

摘 要 本论文主要论述了如何使用django框架开发一个网络空间微博管理信息系统&#xff0c;本系统将严格按照软件开发流程进行各个阶段的工作&#xff0c;面向对象编程思想进行项目开发。在引言中&#xff0c;作者将论述该系统的当前背景以及系统开发的目的&#xff0c;后续章节…

【C/C++ 11】贪吃蛇游戏

一、题目 贪吃蛇游戏机制是通过控制蛇上下左右移动并吃到食物得分。 蛇头碰到墙壁或者碰到蛇身就游戏结束。 食物随机生成&#xff0c;蛇吃到食物之后蛇身变长&#xff0c;蛇速加快。 二、算法 1. 初始化游戏地图并打印&#xff0c;地图的边缘是墙&#xff0c;地图的每个坐…

19.HarmonyOS App(JAVA)依赖布局DependentLayout使用方法

layout/ability_main.xml 显示位置不对&#xff1a;检查布局文件ohos:lef_of "id:tuzi",比如显示在兔子的左侧&#xff0c;这里就会显示不对。 需要id前没有$符号。改为&#xff1a; ohos:lef_of "$id:tuzi" <?xml version"1.0" encodi…

服务器学习

云服务器通常是通过多台物理服务器协同工作来提供的。云服务提供商使用大规模的数据中心&#xff0c;这些数据中心包含许多物理服务器。这些物理服务器上运行着虚拟化技术&#xff0c;允许它们被分割成多个虚拟服务器实例。 当用户请求创建一个云服务器时&#xff0c;云服务提…

FreeCAD的python脚本编写

简介 FreeCAD是一款强大的开源CAD软件&#xff0c;可以与python无缝对解&#xff0c;使用python来驱动三维几何的构建&#xff0c;具有很高的灵活性。本文主要讨论一下录制宏的方法&#xff0c;以及如何驱动特定参数 方法 打开FreeCAD软件&#xff0c;点击录制宏按钮后&…

C++实现鼠标点击和获取鼠标位置(编译环境visual studio 2022)

1环境说明 2获取鼠标位置的接口 void GetMouseCurPoint() {POINT mypoint;for (int i 0; i < 100; i){GetCursorPos(&mypoint);//获取鼠标当前所在位置printf("% ld, % ld \n", mypoint.x, mypoint.y);Sleep(1000);} } 3操作鼠标左键和右键的接口 void Mo…

什么是功能安全?

前言 在上一家公司的时候&#xff0c;有幸参加过公司内部的技术分享会&#xff0c;有一个同事跟我们分享了功能安全的一些内容。在提问环节&#xff0c;我问了一个问题“什么是功能安全&#xff1f;”他回答不上来。这也是我们很多人在工作中常犯的一个问题&#xff1a;我们做了…

汽车租赁系统

目录 一.研究背景 二.系统架构 1、SSM 2、JAVA 3、MySQL 4、系统架构 三.系统功能 1、车辆管理 2、客户管理 3、销售管理 4、统计分析 四.系统实现 五.结论总结 一.研究背景 传统的销售与信息统计管理都主要依靠人工&#xff0c;处理出的销售数据量与使用管理系统…

vcruntime140.dll有什么作用?vcruntime140.dll缺失的解决方法分享

解决因缺少vcruntime140.dll文件引起的问题实际上是相对简单的尽管最近有许多人在抱怨该文件频繁丢失且不知道该如何处理。作为一个责任编辑&#xff0c;我认为有很大的必要向大家清楚地解释一下。让我们从探索vcruntime140.dll文件缺少的修复方法吧。 一.msvcp140.dll的作用 …

基于springboot就业信息管理系统源码和论文

随着信息化时代的到来&#xff0c;管理系统都趋向于智能化、系统化&#xff0c;就业信息管理系统也不例外&#xff0c;但目前国内仍都使用人工管理&#xff0c;市场规模越来越大&#xff0c;同时信息量也越来越庞大&#xff0c;人工管理显然已无法应对时代的变化&#xff0c;而…

2024年美赛数学建模E题思路分析 - 财产保险的可持续性

# 1 赛题 问题E&#xff1a;财产保险的可持续性 极端天气事件正成为财产所有者和保险公司面临的危机。“近年来&#xff0c;世界已经遭受了1000多起极端天气事件造成的超过1万亿美元的损失”。[1]2022年&#xff0c;保险业的自然灾害索赔人数“比30年的平均水平增加了115%”。…

FastCAE合作开发项目:可执行调试的脚本编辑器

开发内容 1. 要求能够编辑脚本内容 2. 要求能够高亮显示关键字、纯数字、单行注释、多行注释等 3. 要求能够设置断点功能 4. 要求能够进行运行求解器、单步运行、暂停、继续、终止等基本调试功能 5. 要求能够高亮执行脚本&#xff0c;分别展示单脚本行执行中与执行完成效果…

更新npm镜像源:淘宝镜像已过期,及时切换!

你好&#xff0c;我是小白Coding日志&#xff0c;一个热爱技术的程序员。在这里&#xff0c;我分享自己在编程和技术世界中的学习心得和体会。希望我的文章能够给你带来一些灵感和帮助。欢迎来到我的博客&#xff0c;一起在技术的世界里探索前行吧&#xff01; 前言 就在昨天…

第二卷《皈依的意义与方法》

甲二、别明皈依的方法 分二&#xff1a;初、事相皈依。二、理体皈依。 前面一科讲到“皈依的意义”——“能皈依的心”跟“所皈依的境”。 “能皈依的心”就是我们有一种祈求救护的心情&#xff1b;“所皈依的境”有二种&#xff1a;一种是“住持三宝”&#xff0c;或者讲外…

Git快速入门+常用指令+提交规范

目录 Git创建本地仓库 IDEA集成Git Git和IDEA连接使用2 忽略文件 本地仓库常用命令 远程仓库常用命令 分支常用命令 标签操作 提交规范 Git创建本地仓库 1、创建一个文件夹&#xff0c;右键选择Git Bash Here 2、选择下列其中一个方法 方法一&#xff1a;创建初始化…

【算法与数据结构】583、72、LeetCode两个字符串的删除操作+编辑距离

文章目录 一、583、两个字符串的删除操作二、72、编辑距离三、完整代码 所有的LeetCode题解索引&#xff0c;可以看这篇文章——【算法和数据结构】LeetCode题解。 一、583、两个字符串的删除操作 思路分析&#xff1a;本题的思路和115、不同的子序列差不多&#xff0c;只是变成…

vue3+threejs+koa可视化项目——模型文件上传(第四步)

文章目录 ⭐前言&#x1f496;往期node系列文章&#x1f496;threejs系列相关文章&#x1f496;vue3threejs系列 ⭐koa后端文件上传(koa-body)&#x1f496;自动创建目录&#x1f496;自定义目录上传&#x1f496;apifox自测上传接口 ⭐vue3前端上传模型文件&#x1f496; axio…