当前位置: 首页 > news >正文

MySQL insert 记录后查询是乱码问题分析

问题现象

后台应用程序使用的是云上的 MySQL 服务,需要给 MySQL 数据表里 insert 一些数据,平时都是先运行一个 MySQL 的 pod:

kubectl run mysql-client --rm -it --restart='Never' --image mysql:5.7 --command -- env LANG=C.UTF-8 mysql -hx.x.x.x -uusername -ppassword

然后将 insert SQL 文件复制到 MySQL pod 里面,在 MySQL pod 中执行 source SQL 文件命令。这次 insert 数据时发现环境上已经有运行的 MySQL pod了,就将 SQL 文件复制到已运行的 MySQL pod中,然后通过命令进入到MySQL pod里,再连接到云上 MySQL:

kubectl exec -it mysql-client -- bash
mysql -hx.x.x.x -uusername -ppassword

接着执行 source SQL文件,然后通过前端页面查看录入的数据,发现是乱码。但是在执行 source 命令的 MySQL 客户端 select 查询录入的数据却是预期的中文字符。

问题原因

例如 source 执行的 SQL文件中的 SQL 语句是

INSERT INTO table_1 (title) VALUES ('好');
  1. SQL文件是UTF8编码的,MySQL 客户端向 MySQL 服务器发送的 title 字段值的 “好” 的 UTF8编码字节序列,十六进制表示是 E5A5BD。

  2. mysql-client pod的字符集是 POSIX,MySQL 客户端向 MySQL 服务器发送数据采用的就是 latin1编码,MySQL 服务器收到数据后,使用 latin1 解码 E5A5BD ,得到字符串 好。

    root@mysql-client:/# locale
    LANG=
    LANGUAGE=
    LC_CTYPE="POSIX"
    LC_NUMERIC="POSIX"
    LC_TIME="POSIX"
    LC_COLLATE="POSIX"
    LC_MONETARY="POSIX"
    LC_MESSAGES="POSIX"
    LC_PAPER="POSIX"
    LC_NAME="POSIX"
    LC_ADDRESS="POSIX"
    LC_TELEPHONE="POSIX"
    LC_MEASUREMENT="POSIX"
    LC_IDENTIFICATION="POSIX"
    LC_ALL=mysql> show variables like 'character_set_%';
    +--------------------------+----------------------------+
    | Variable_name            | Value                      |
    +--------------------------+----------------------------+
    | character_set_client     | latin1                     |
    | character_set_connection | latin1                     |
    | character_set_database   | utf8                       |
    | character_set_filesystem | binary                     |
    | character_set_results    | latin1                     |
    | character_set_server     | utf8                       |
    | character_set_system     | utf8                       |
    | character_sets_dir       | /usr/share/mysql/charsets/ |
    +--------------------------+----------------------------+
    8 rows in set (0.01 sec)
  3. 由于数据表字段的字符集是 UTF8,MySQL 服务器再将字符串 好 用 UTF8 编码得到字节序列 C3A5C2A5C2BD,这个可以通过如下 SQL 语句查询证实。

    select HEX(title) from table_1;
    

这里说一下在验证此过程时遇到的问题:

刚开始使用的中文字符“我”进行验证,对应的 UTF8 编码是 e68891,88 和 91 (位于 80 和 9f 之间)在 latin1 编码中对应的是控制字符,手动解码后的字符不是正常字符,再使用 UTF8 编码时为 C3A6C288C291,和数据表中存储的 C3A6CB86E28098 不一样(MySQL 代码中编码肯定对控制字符进行了正确编码),为了避免控制字符,想到选用不在 80 和 9f 之间的中文字符“好” E5A5BD ,这样手动编码后和数据表存储的都是 C3A5C2A5C2BD,这才验证了这个过程。

页面查询乱码的原因:

前端页面通过调用后台接口查询数据,后台服务连接 MySQL 使用的字符集是 UTF8,所以character_set_results 就是 UTF8。

MySQL 服务器从数据表中查询的字节序列是 C3A5C2A5C2BD,数据表字段的编码也是 UTF8,和 character_set_results 一样,发送给后台服务客户端的字节序列就是 C3A5C2A5C2BD。

后台服务使用 UTF8 对 C3A5C2A5C2BD 解码得到 好,所以前端页面显示的就是 好,而不是预期的中文字符 ”好“。

MySQL 命令行客户端select 查询正常的原因:

MySQL 命令行客户端 session 的 character_set_results 是 latin1 。

MySQL 服务器从数据表中查询的字节序列是 C3A5C2A5C2BD,使用 UTF8 解码后是 好。

再使用 character_set_results 的字符集 latin1 进行编码得到 E5A5BD,将字符序列 E5A5BD 发送给 MySQL 命令行客户端。

再发送给本地的图形界面的终端模拟器 MobaXterm,MobaXterm 使用的字符集是 UTF8,使用 UTF8 对 E5A5BD 解码输出中文字符“好”。

解决方法

  • 连接云上 MySQL 时指定字符集为 utf8

    mysql -hx.x.x.x -uusername -ppassword --default-character-set=utf8
    
  • 将 MySQL pod 的字符编码设置为 UTF8, 这样 MySQL 客户端连接服务器时使用的字符集就是 utf8

    export LANG=C.UTF-8
    

    或者直接在如下命令启动的 MySQL 客户端中执行 source 命令,此命令通过 env LANG=C.UTF-8 设置了 pod的字符编码为 UTF8:

    kubectl run mysql-client --rm -it --restart='Never' --image mysql:5.7 --command -- env LANG=C.UTF-8 mysql -hx.x.x.x -uusername -ppassword
    

这样,MySQL 的 character_set_client、character_set_connection、character_set_results都会设置为 utf8, 就和数据表字段的字符集保持一致,不会出现乱码问题。

mysql> show variables like 'character_set_%';
+--------------------------+----------------------------+
| Variable_name            | Value                      |
+--------------------------+----------------------------+
| character_set_client     | utf8                       |
| character_set_connection | utf8                       |
| character_set_database   | utf8                       |
| character_set_filesystem | binary                     |
| character_set_results    | utf8                       |
| character_set_server     | utf8                       |
| character_set_system     | utf8                       |
| character_sets_dir       | /usr/share/mysql/charsets/ |
+--------------------------+----------------------------+
8 rows in set (0.00 sec)

MySQL 客户端和服务器通信中的字符集处理

客户端给服务器发送消息过程

  1. 如果 mysql 命令中没有指定 --default-character-set 参数,客户端使用操作系统字符集对消息编码发送给服务器,否则使用 --default-character-set 参数的字符集对消息编码。

  2. 服务器将 character_set_client、 character_set_connection、character_set_results 设置为客户端的字符集。

  3. 收到客户端的消息后,使用 character_set_client 字符集对消息解码。

  4. 再用 character_set_connection 对应的字符集对解码后的消息编码后处理。

    服务器处理消息时要转换为 character_set_connection 字符集进行处理,比较规则只有 connection 有,character_set_client 和 character_set_results 都没有:

    mysql> show variables like 'collation_%';
    +----------------------+-------------------+
    | Variable_name        | Value             |
    +----------------------+-------------------+
    | collation_connection | latin1_swedish_ci |
    | collation_database   | utf8_general_ci   |
    | collation_server     | utf8_general_ci   |
    +----------------------+-------------------+
    3 rows in set (0.00 sec)
    

服务器给客户端发送消息过程

  1. 服务器从数据表中查询字段内容
  2. 将字符内容先使用字段的字符集解码,再使用 character_set_results 字符集编码后发给客户端。
  3. 客户端使用操作系统的字符集解码消息进行展示,这里对于使用本地图形界面的终端模拟器登录远程主机的场景来说,消息还会发送到本地图形界面的终端模拟器,使用终端模拟器的字符集对消息解码再展示出来。

相关文章:

MySQL insert 记录后查询是乱码问题分析

问题现象 后台应用程序使用的是云上的 MySQL 服务,需要给 MySQL 数据表里 insert 一些数据,平时都是先运行一个 MySQL 的 pod: kubectl run mysql-client --rm -it --restartNever --image mysql:5.7 --command -- env LANGC.UTF-8 mysql -…...

字符串算法之AC 自动机(Aho-Corasick Algorithm, 多模式匹配)详细解读

AC自动机(Aho-Corasick Algorithm)是一种高效的多模式字符串匹配算法,用于同时查找多个模式串(子串)在文本串中的出现位置。它结合了字典树(Trie)和有限状态机(Finite State Machine…...

YoloV10改进:Block改进|使用ContextAggregation模块改善C2f模块|即插即用

摘要 在计算机视觉领域,目标检测与实例分割任务一直是研究的热点。YoloV10作为目标检测领域的佼佼者,凭借其出色的性能和效率赢得了广泛的认可。然而,随着技术的不断进步,如何进一步提升YoloV10的性能成为了我们追求的目标。近期…...

学习之高阶编程str方法

__str__方法 问题思考:交互环境下print打印的内容和和直接输入变量,返回的内容不一样这是为什么?. 使用print打印的时候触发的是_str_方法, 注意点: 重写str,必须要记得写return. return返回的必须是一个字符串对象。 class MyClass:def _…...

FreeRTOS:事件标志组

目录 一、简介 二、 事件控制块 三、相关API 四、 应用场景 一、简介 在FreeRTOS中,使用信号量可以实现同步,但是使用信号量来同步的话任务只能与单个的任务进行同步。有时候某个任务可能会需要与多个任务进行同步,此时信号量就无能为力。…...

【高分论文密码】AI赋能大尺度空间模拟与不确定性分析及数字制图

随着AI大语言模型的广泛应用,大尺度空间模拟预测与数字制图技术在不确定性分析中的重要性日益凸显。这些技术已经成为撰写高分SCI论文的关键工具,被誉为“高分论文密码”。大尺度模拟技术能够从不同的时空尺度揭示农业生态环境领域的内在机理和时空变化规…...

智能摆件(墨水屏)

因为需要申请8k的堆,所以需要更改堆的大小 stm32修改堆栈大小(堆栈空间不足导致死机)_minimum heap size-CSDN博客...

ansible————playbook

一、playbook和ad hoc命令 ad hoc命令是单行,一个简单的任务,运行一次。ansible真正强大的地方是使用ansible的playbook重复运行多次复杂的任务。 一个play是是一组有序的任务,该paly对应着在inventory被选择的主机。一个playbook是一个包含…...

linux日志分割工具logorate快速验证配置是否有效

创建一些文件, 并修改文件的mtime(修改时间) # /var/log/test/*.log touch -d "2024-10-14" test1.log touch -d "2024-10-15" test2.log touch -d "2024-10-16" test3.log touch -d "2024-10-17" test4.log#快速创建一个1G的大文…...

Unity3D URP画面品质的上限如何详解

Unity3D是一款广泛应用于游戏开发的引擎,它提供了多种渲染管线用于实现不同的画面品质。其中一种渲染管线是Universal Render Pipeline(简称URP),它是Unity3D的一种轻量级渲染管线,专注于提供高性能和可移植性。 对惹…...

风管阻力计算

风管阻力主要包括摩擦阻力和局部阻力两大类。摩擦阻力:空气在风管内流动时,与管壁的摩擦作用导致的能量损失,与管道长度、断面尺寸、风速、空气密度等参数有关。局部阻力:风管系统中的弯头、三通、变径、阀门等部件,由于改变了气流的流动方向或速度,导致的额外能量损失,用局部阻…...

【redis】redis的多线程和IO多路复用

【redis】redis的多线程和IO多路复用 【一】前言【二】Redis单线程和多线程问题的背景【1】Redis的单线程【2】Redis为什么选择单线程?【3】Redis为什么开始利用多核?【4】Redis当前的性能瓶颈【5】Redis的主线程如何和IO线程协同 【三】IO多路复用的理解…...

webstorm 编辑器配置及配置迁移

1.下载地址 WebStorm:JetBrains 出品的 JavaScript 和 TypeScript IDE 其他版本下载地址 2.安装 点击下一步安装,可根据需要是否删除已有版本 注意: 完成安装后需要激活 3.设置快捷键 以下为个人常用可跳过或根据需要设置 如&#xff1a…...

Oracle19.25发布,如何打补丁到19.25

一. 19.25发布 2024年10月16日 19c 19.25补丁发布 文档编号19202410.9,文档编码规则: 19(版本号)2024(年份)07(当季的第一个月01/04/07/10).9 一般每个季度的首月中15号左右发布…...

vue3中,拦截双击事件的第一次点击,写一些逻辑

在 Vue 3 中&#xff0c;如果想要拦截双击事件的第一次点击并执行一些逻辑&#xff0c;你可以使用一个状态变量来跟踪第一次点击事件&#xff0c;并在第二次点击时阻止第一次点击逻辑的执行。以下是一个实现示例&#xff1a; <template><divmousedown"handleMou…...

落地 ZeroETL 轻量化架构,ByteHouse 推出“四个一体化”策略

在数字化转型的浪潮中&#xff0c;数据仓库作为企业的核心数据资产&#xff0c;其重要性日益凸显。随着业务范围扩大&#xff0c;企业也会使用不同的数据仓库来管理、维护相关数据。研发人员需要花费大量时间和精力&#xff0c;从中导出数据&#xff0c;然后进行手动整理、转换…...

如何提高LabVIEW编程效率

提高LabVIEW编程效率对开发者来说非常重要&#xff0c;尤其是在处理复杂项目或紧迫的开发周期时。以下是一些可以显著提升LabVIEW编程效率的技巧&#xff0c;从代码结构、工具使用到团队协作的多个角度进行详细分析&#xff1a; 1. 模块化设计 模块化设计 是提高代码可维护性和…...

Android 开发 TabLayout 自定义指示器长度

前言 原生 TabLayout 的指示器长度是充满整个屏幕的&#xff0c;但在实际开发中 UI 会设计成 指示器的长度等于或者小于标题字体长度&#xff0c;如图 如果设置成跟字体长度一样即使用 API: mTabLayout.setTabIndicatorFullWidth(false);或者在 xml 布局文件中的TabLayout标签…...

构造mex(牛客周赛 Round 59)

题目链接&#xff1b; D-构造mex_牛客周赛 Round 59 (nowcoder.com) 题目描述&#xff1a; 输出和输出描述&#xff1a; 输入样例&#xff1a; 3 6 3 3 7 4 3 6 6 0 输出样例&#xff1a; NO YES 4 0 1 2 YES 1 1 1 1 1 1 分析&#xff1a; 数学思维题&#xff0c;赛后看了一…...

RabbitMQ 交换机的类型

在 RabbitMQ 中&#xff0c;交换机&#xff08;Exchange&#xff09;是一个核心组件&#xff0c;负责接收来自生产者的消息&#xff0c;并根据特定的路由规则将消息分发到相应的队列。交换机的存在改变了消息发送的模式&#xff0c;使得消息的路由更加灵活和高效。 交换机的类…...

Vue记事本应用实现教程

文章目录 1. 项目介绍2. 开发环境准备3. 设计应用界面4. 创建Vue实例和数据模型5. 实现记事本功能5.1 添加新记事项5.2 删除记事项5.3 清空所有记事 6. 添加样式7. 功能扩展&#xff1a;显示创建时间8. 功能扩展&#xff1a;记事项搜索9. 完整代码10. Vue知识点解析10.1 数据绑…...

设计模式和设计原则回顾

设计模式和设计原则回顾 23种设计模式是设计原则的完美体现,设计原则设计原则是设计模式的理论基石, 设计模式 在经典的设计模式分类中(如《设计模式:可复用面向对象软件的基础》一书中),总共有23种设计模式,分为三大类: 一、创建型模式(5种) 1. 单例模式(Sing…...

AtCoder 第409​场初级竞赛 A~E题解

A Conflict 【题目链接】 原题链接&#xff1a;A - Conflict 【考点】 枚举 【题目大意】 找到是否有两人都想要的物品。 【解析】 遍历两端字符串&#xff0c;只有在同时为 o 时输出 Yes 并结束程序&#xff0c;否则输出 No。 【难度】 GESP三级 【代码参考】 #i…...

ETLCloud可能遇到的问题有哪些?常见坑位解析

数据集成平台ETLCloud&#xff0c;主要用于支持数据的抽取&#xff08;Extract&#xff09;、转换&#xff08;Transform&#xff09;和加载&#xff08;Load&#xff09;过程。提供了一个简洁直观的界面&#xff0c;以便用户可以在不同的数据源之间轻松地进行数据迁移和转换。…...

SpringCloudGateway 自定义局部过滤器

场景&#xff1a; 将所有请求转化为同一路径请求&#xff08;方便穿网配置&#xff09;在请求头内标识原来路径&#xff0c;然后在将请求分发给不同服务 AllToOneGatewayFilterFactory import lombok.Getter; import lombok.Setter; import lombok.extern.slf4j.Slf4j; impor…...

CSS设置元素的宽度根据其内容自动调整

width: fit-content 是 CSS 中的一个属性值&#xff0c;用于设置元素的宽度根据其内容自动调整&#xff0c;确保宽度刚好容纳内容而不会超出。 效果对比 默认情况&#xff08;width: auto&#xff09;&#xff1a; 块级元素&#xff08;如 <div>&#xff09;会占满父容器…...

论文阅读笔记——Muffin: Testing Deep Learning Libraries via Neural Architecture Fuzzing

Muffin 论文 现有方法 CRADLE 和 LEMON&#xff0c;依赖模型推理阶段输出进行差分测试&#xff0c;但在训练阶段是不可行的&#xff0c;因为训练阶段直到最后才有固定输出&#xff0c;中间过程是不断变化的。API 库覆盖低&#xff0c;因为各个 API 都是在各种具体场景下使用。…...

提升移动端网页调试效率:WebDebugX 与常见工具组合实践

在日常移动端开发中&#xff0c;网页调试始终是一个高频但又极具挑战的环节。尤其在面对 iOS 与 Android 的混合技术栈、各种设备差异化行为时&#xff0c;开发者迫切需要一套高效、可靠且跨平台的调试方案。过去&#xff0c;我们或多或少使用过 Chrome DevTools、Remote Debug…...

mac:大模型系列测试

0 MAC 前几天经过学生优惠以及国补17K入手了mac studio,然后这两天亲自测试其模型行运用能力如何&#xff0c;是否支持微调、推理速度等能力。下面进入正文。 1 mac 与 unsloth 按照下面的进行安装以及测试&#xff0c;是可以跑通文章里面的代码。训练速度也是很快的。 注意…...

《Docker》架构

文章目录 架构模式单机架构应用数据分离架构应用服务器集群架构读写分离/主从分离架构冷热分离架构垂直分库架构微服务架构容器编排架构什么是容器&#xff0c;docker&#xff0c;镜像&#xff0c;k8s 架构模式 单机架构 单机架构其实就是应用服务器和单机服务器都部署在同一…...