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

mysql字符串等值查询中条件字段值末尾有空格也能查到数据问题

一、事故还原

我们仍然使用学生信息表,但是我们只需要保留两个字段即可:
CREATE TABLE `student_info` (`id` int(11) NOT NULL AUTO_INCREMENT COMMENT '学号',`name` varchar(20) CHARACTER SET utf8 DEFAULT NULL COMMENT '姓名',  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='学生基本信息表';
先插入三条数据备用:
#尾部无空格
INSERT INTO `student_info` (`name`) VALUES ('duduu');
#尾部带一个空格
INSERT INTO `student_info` (`name`) VALUES ('duduu ');
#尾部带两个空格
INSERT INTO `student_info` (`name`) VALUES ('duduu  ');

需要注意的是,name字段值分别是:不带空格的duduu、带一个空格的duduu、带两个空格的duduu,且空格都是加在了尾部。我们查询这几条记录的name字段的长度:

mysql> select length(name) from student_info;
+--------------+
| length(name) |
+--------------+
|            5 |
|            6 |
|            7 |
+--------------+
3 rows in set (0.00 sec)

这个结果是符合预期的,MySQL检索CHAR类型的数据时,CHAR类型的字段会去除尾部的空格;检索VARCHAR类型的字段数据时,会保留数据尾部的空格,因此这里的长度分别是5、6、7。我们针对name做简单的等值查询试试:

#不带空格的duduu
mysql> select * from student_info where name='duduu';
+----+---------+
| id | name    |
+----+---------+
|  1 | duduu   |
|  2 | duduu   |
|  3 | duduu   |
+----+---------+
3 rows in set (0.00 sec)#带一个空格
mysql> select * from student_info where name='duduu ';
+----+---------+
| id | name    |
+----+---------+
|  1 | duduu   |
|  2 | duduu   |
|  3 | duduu   |
+----+---------+
3 rows in set (0.00 sec)#带两个空格
mysql> select * from student_info where name='duduu  ';
+----+---------+
| id | name    |
+----+---------+
|  1 | duduu   |
|  2 | duduu   |
|  3 | duduu   |
+----+---------+
3 rows in set (0.00 sec)

我们会发现,无论后面带多少空格,我们始终可以把所有的用户信息都查询出来,这个并不符合我们的预期啊!!!如果我们将空格都放在最前面呢?会发生什么事情?我们来试试。删除表数据后,重新插入数据:

#前面无空格
INSERT INTO `student_info` (`name`) VALUES ('duduu');
#前面带一个空格
INSERT INTO `student_info` (`name`) VALUES (' duduu');
#前面带两个空格
INSERT INTO `student_info` (`name`) VALUES ('  duduu');
此时分别计算字段字符长度:
mysql> select * from student_info; 
+----+---------+
| id | name    |
+----+---------+
|  1 | duduu   |
|  2 |  duduu  |
|  3 |   duduu |
+----+---------+
3 rows in set (0.00 sec)mysql> select length(name) from student_info;
+--------------+
| length(name) |
+--------------+
|            5 |
|            6 |
|            7 |
+--------------+
3 rows in set (0.00 sec)
可以看到空格放在前面和放在后面的查询结果是不一样的,这个倒不是我们关注的重点,我们关注等值查询是否可以正常查询出来:
#不带空格的duduu
mysql> select * from student_info where name='duduu';
+----+-------+
| id | name  |
+----+-------+
|  1 | duduu |
+----+-------+
1 row in set (0.00 sec)#带一个空格
mysql> select * from student_info where name=' duduu';
+----+--------+
| id | name   |
+----+--------+
|  2 |  duduu |
+----+--------+
1 row in set (0.00 sec)#带两个空格
mysql> select * from student_info where name='  duduu';
+----+---------+
| id | name    |
+----+---------+
|  3 |   duduu |
+----+---------+
1 row in set (0.00 sec)
通过实验发现,当空格放在前面时,等值查询是没有问题的,但是空格放在后面时,等值查询并不符合我们的预期。

二、合理推测

通过上面的实验,明明是三个长度不同的字符串,空格放在前边被认为是不同,放在后边又被认为是相同,难道说:对于MySQL来说,字符串做字符串等值判断时会忽略后面的空格,duduu(不带空格)、duduu(后面带一个空格)、duduu(后面带两个空格),都被认作是不带空格的duduu了吗?既然MySQL认为这三个字符串是一个,那么我们看看给name增加唯一索引时,插入这几条数据会不会报错。我们索性重新准备学生信息表:
CREATE TABLE `student_info` (`id` int(11) NOT NULL AUTO_INCREMENT COMMENT '学号',`name` varchar(20) CHARACTER SET utf8 DEFAULT NULL COMMENT '姓名',UNIQUE KEY uk_name (name),PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='学生基本信息表';
此时插入数据:
mysql> #尾部无空格
mysql> INSERT INTO `student_info` (`name`) VALUES ('duduu');
Query OK, 1 row affected (0.00 sec)mysql> #尾部带一个空格
mysql> INSERT INTO `student_info` (`name`) VALUES ('duduu ');
ERROR 1062 (23000): Duplicate entry 'duduu ' for key 'uk_name'
mysql> #尾部带两个空格
mysql> INSERT INTO `student_info` (`name`) VALUES ('duduu  ');
ERROR 1062 (23000): Duplicate entry 'duduu  ' for key 'uk_name'
不出所料,进行字符串等值判断时,MySQl认为duduu(不带空格)、duduu(后面带一个空格)、duduu(后面带两个空格)是重复的三个字符串,后面两条数据由于违背了唯一性,因而不可以被插入,我们去官方文档看看有没有提及这一点。

三、权威文档

官方文档链接:https://dev.mysql.com/doc/refman/5.7/en/char.html有提到这样的描述:

MySQL的校对规则基于PAD SPACE,这就意味着CHAR、VARCHAR、TEXT等字符串的等值比较(“=”)会忽略掉尾部的空格。但是这个规则不包括LIKE这样的模糊查询语句。图中代码示例说明的是使用=这样的等值查询时会自动忽略后面的空格,'Jones'和'Jones '都可以被查询到,但是Like需要精准匹配上空格才行。

四、解决思路

既然=查询会自动忽略后面的空格,如何解决呢?下面有两个思路。

🧷思路一:LIKE

如上所提到,官方文档给出了一个思路,即使用like。LIKE是基于逐个字符进行比较的,这样就不会忽略尾部的空格,官方文档有所提及:https://dev.mysql.com/doc/refman/5.7/en/string-comparison-functions.html

我们来实验下:

#不带空格的duduu
mysql> select * from student_info where name like 'duduu';
+----+-------+
| id | name  |
+----+-------+
|  1 | duduu |
+----+-------+
1 row in set (0.00 sec)#带一个空格
mysql> select * from student_info where name like 'duduu ';
+----+--------+
| id | name   |
+----+--------+
|  2 | duduu  |
+----+--------+
1 row in set (0.00 sec)#带两个空格
mysql> select * from student_info where name like 'duduu  ';
+----+---------+
| id | name    |
+----+---------+
|  3 | duduu   |
+----+---------+
1 row in set (0.00 sec)
这里可以得到两个结论:
  • LIKE后面的字段可以不带通配符;
  • LIKE是基于逐个字符进行比较的,这样就不会忽略尾部的空格

🧷思路二:BINARY

BINARY不是函数,是类型转换运算符,它用来强制它后面的字符串转为二进制字节,再逐个字节比较,也可以理解成精确匹配,官网上面有这样的描述:https://dev.mysql.com/doc/refman/5.7/en/cast-functions.html#operator_binary

可以看到,空格在BINARY转换后并不会被忽略,那么我们再使用BINARY进行等值查询进行验证:

#不带空格的duduu
mysql> select * from student_info where name = BINARY 'duduu';
+----+-------+
| id | name  |
+----+-------+
|  1 | duduu |
+----+-------+
1 row in set (0.00 sec)#带一个空格
mysql> select * from student_info where name = BINARY 'duduu ';
+----+--------+
| id | name   |
+----+--------+
|  2 | duduu  |
+----+--------+
1 row in set (0.00 sec)#带两个空格
mysql> select * from student_info where name = BINARY 'duduu  ';
+----+---------+
| id | name    |
+----+---------+
|  3 | duduu   |
+----+---------+
1 row in set (0.00 sec)

可见BINARY也可以解决此问题。

五、总结

本文的结论如下:

  • 在存储时,不会自动截断尾部的空格,会按原值存储;

  • MySQL的CHAR、VARCHAR、TEXT等字符串字段在等值比较("=")时,基于PAD SPACE校对规则,会忽略掉尾部的空格;

  • 如果想要精确查询就不能用等值查询("="),而应改用LIKE或BINARY;

相关文章:

mysql字符串等值查询中条件字段值末尾有空格也能查到数据问题

一、事故还原 我们仍然使用学生信息表,但是我们只需要保留两个字段即可: CREATE TABLE student_info (id int(11) NOT NULL AUTO_INCREMENT COMMENT 学号,name varchar(20) CHARACTER SET utf8 DEFAULT NULL COMMENT 姓名, PRIMARY KEY (id) ) ENGINEIn…...

一个关于事件溯源Event Sourcing的小荔枝,Golang实现

最后更新于2023年3月1日 10:23:13 参考的这个文章:https://martinfowler.com/eaaDev/EventSourcing.html 用C sharp实现的,我改写成Golang了 最简单的例子 func main() {eProc : NewEventProcessor()//refact : Cargo{Name: "Refactoring"}…...

Vue3 组合式函数,实现minxins

截至目前,组合式函数应该是在VUE 3应用程序中组织业务逻辑最佳的方法。它让我们可以把一些小块的通用逻辑进行抽离、复用,使我们的代码更易于编写、阅读和维护。 一. 什么是“组合式函数”? 根据官方文档说明,在 Vue 应用的概念中…...

什么是钉钉消息推送?

我是3y,一年CRUD经验用十年的markdown程序员👨🏻‍💻常年被誉为职业八股文选手 在前阵子我就已经接入了钉钉的群机器人和工作消息推送,一直没写文章同步到给大家。 像这种接入渠道的工作,虽然我没接入过&…...

利用 NVIDIATAO 和 WeightBias 加速AI开发

利用 NVIDIATAO 和 Weight&Bias 加速AI开发 利用图像分类、对象检测、自动语音识别 (ASR) 和其他形式的 AI 可以推动公司和商业部门内部的大规模转型。 然而,从头开始构建人工智能和深度学习模型是一项艰巨的任务。 构建这些模型的一个共同先决条件是拥有大量高…...

token - 令牌

文章目录token - 令牌学前须知:1,base64 防君子不防小人2,SHA-256 安全散列算法的一种(hash)3,HMAC-SHA2564,RSA256 非对称加密2.1 JWT - json-web-token1,三大组成2,jwt…...

应用模型开发指南上新介绍

Module、HAP、Ability、AbilitySta-ge、Context……您是否曾经被这些搞不懂又绕不开的知识点困扰? 现在,全新的《应用程序包基础知识》及《应用模型开发指南》为您答疑解惑! 这里有您关注的概念解析、原理机制阐述,也有丰富的…...

Dbeaver连接Hive数据库操作指导

背景:由于工作需要,当前分析研究的数据基于Hadoop的Hive数据库中,且Hadoop服务端无权限进行操作且使用安全模式,在研究了Dbeaver、Squirrel和Hue三种连接Hive的工具,在无法绕开useKey认证的情况下,只能使用…...

【RabbitMQ笔记09】消息队列RabbitMQ之常见方法的使用

这篇文章,主要介绍消息队列RabbitMQ之常见方法的使用。 目录 一、消息队列常见方法 1.1、连接工厂ConnectionFactory 1.2、连接Connection 1.3、通道Channel 1.4、交换机相关方法 (1)exchangeDeclare()声明交换机 1.5、队列相关方法 …...

Linux字符设备驱动模型之设备号

从上文中可知,在Linux用户空间中,如若需要操作硬件设备,均通过/dev目录下的设备文件节点进行操作,基本上每一种设备都会存在一个或者多个的设备节点。 并且在Linux内核中,其表示字符设备的结构成员也提供了相应的设备号…...

C++多态原理

请看下面的程序&#xff0c;该程序演示了多态类对象存储空间的大小。 #include <iostream> using namespace std; class A {public:int i;virtual void func() {}virtual void func2() {} }; class B : public A {int j;void func() {} }; int main() {cout << si…...

PMP认证与NPDP认证哪个含金量高?

两个证涉及的领域不一样的&#xff0c;一个是项目管理&#xff0c;对应的是项目经理&#xff1b;一个是产品管理&#xff0c;对应的是产品经理。含金量不能相比&#xff0c;但在各自的领域的含金量是很高的&#xff0c;至少专业程度或者知名度是最高的。 我来分别说一下PMP认证…...

改进YOLOv7-Tiny系列:首发改进结合BiFPN结构的特征融合网络,网络融合更多有效特征,高效涨点

💡该教程为改进进阶指南,属于《芒果书》📚系列,包含大量的原创首发改进方式, 所有文章都是全网首发原创改进内容🚀 内容出品:CSDN博客独家更新 @CSDN芒果汁没有芒果 💡本篇文章 基于 YOLOv5、YOLOv7芒果改进YOLO系列:芒果改进YOLOv7-Tiny系列:首发改进结合BiFPN结…...

PPC Insights系列:洞见安全多方图联邦

开放隐私计算开放隐私计算开放隐私计算OpenMPC是国内第一个且影响力最大的隐私计算开放社区。社区秉承开放共享的精神&#xff0c;专注于隐私计算行业的研究与布道。社区致力于隐私计算技术的传播&#xff0c;愿成为中国 “隐私计算最后一公里的服务区”。183篇原创内容公众号知…...

SQLite注入记录(目前最全、核心函数用法、布尔盲注、时间盲注、webshell、动态库,绕过方式)

目录 与Mysql区别 全部核心函数 普通注入 查询所有列 查看所有表名...

Java简单的生成/解析二维码(zxing qrcode)

Hi I’m Shendi Java简单的生成/解析二维码&#xff08;zxing qrcode&#xff09; 在之前使用 qrcode.js 方式生成二维码&#xff0c;但在不同设备上难免会有一些兼容问题&#xff0c;于是改为后端&#xff08;Java&#xff09;生成二维码图片 这里使用 Google 的 zxing包 Jar…...

若依项目导出后端响应的Excel文件流处理

若依开源项目&#xff1a;http://doc.ruoyi.vip/ruoyi-vue 问题 前端 1. download.js 添加自定义方法 /*** 自定义方法&#xff1a;导出后端响应的 excel 文件流* param url 请求后端的接口地址 例如&#xff1a;"/downloadExcel"* param name 响应后的文件名称&…...

华为OD机试【独家】提供C语言题解 - 数组排序

最近更新的博客 华为od 2023 | 什么是华为od,od 薪资待遇,od机试题清单华为OD机试真题大全,用 Python 解华为机试题 | 机试宝典【华为OD机试】全流程解析+经验分享,题型分享,防作弊指南)华为od机试,独家整理 已参加机试人员的实战技巧文章目录 最近更新的博客使用说明数组…...

JVM详解——内存结构

文章目录内存结构1、 运行时数据区2、虚拟机栈3、本地方法栈4、程序计数器5、 堆6、方法区7、运行时常量池8、内存溢出和内存泄漏9、 堆溢出内存结构 1、 运行时数据区 Java虚拟机在运行Java程序期间将管理的内存划分为不同的数据区&#xff0c;不同的区域负责不同的职能&…...

Jvisualvm监控Tomcat以及相关参数优化

Tomcat阻塞模式 阻塞模式&#xff08;BIO&#xff09; 客户端和服务器创建一个连接&#xff0c;它就会创建一个线程来处理这个连接&#xff0c;以为这客户端创建了几个连接&#xff0c;服务端就需要创建几个线程来处理你&#xff0c;导致线程会产生很多&#xff0c;有很多线程…...

vscode里如何用git

打开vs终端执行如下&#xff1a; 1 初始化 Git 仓库&#xff08;如果尚未初始化&#xff09; git init 2 添加文件到 Git 仓库 git add . 3 使用 git commit 命令来提交你的更改。确保在提交时加上一个有用的消息。 git commit -m "备注信息" 4 …...

【Python】 -- 趣味代码 - 小恐龙游戏

文章目录 文章目录 00 小恐龙游戏程序设计框架代码结构和功能游戏流程总结01 小恐龙游戏程序设计02 百度网盘地址00 小恐龙游戏程序设计框架 这段代码是一个基于 Pygame 的简易跑酷游戏的完整实现,玩家控制一个角色(龙)躲避障碍物(仙人掌和乌鸦)。以下是代码的详细介绍:…...

深入剖析AI大模型:大模型时代的 Prompt 工程全解析

今天聊的内容&#xff0c;我认为是AI开发里面非常重要的内容。它在AI开发里无处不在&#xff0c;当你对 AI 助手说 "用李白的风格写一首关于人工智能的诗"&#xff0c;或者让翻译模型 "将这段合同翻译成商务日语" 时&#xff0c;输入的这句话就是 Prompt。…...

java 实现excel文件转pdf | 无水印 | 无限制

文章目录 目录 文章目录 前言 1.项目远程仓库配置 2.pom文件引入相关依赖 3.代码破解 二、Excel转PDF 1.代码实现 2.Aspose.License.xml 授权文件 总结 前言 java处理excel转pdf一直没找到什么好用的免费jar包工具,自己手写的难度,恐怕高级程序员花费一年的事件,也…...

《Playwright:微软的自动化测试工具详解》

Playwright 简介:声明内容来自网络&#xff0c;将内容拼接整理出来的文档 Playwright 是微软开发的自动化测试工具&#xff0c;支持 Chrome、Firefox、Safari 等主流浏览器&#xff0c;提供多语言 API&#xff08;Python、JavaScript、Java、.NET&#xff09;。它的特点包括&a…...

pam_env.so模块配置解析

在PAM&#xff08;Pluggable Authentication Modules&#xff09;配置中&#xff0c; /etc/pam.d/su 文件相关配置含义如下&#xff1a; 配置解析 auth required pam_env.so1. 字段分解 字段值说明模块类型auth认证类模块&#xff0c;负责验证用户身份&am…...

微信小程序 - 手机震动

一、界面 <button type"primary" bindtap"shortVibrate">短震动</button> <button type"primary" bindtap"longVibrate">长震动</button> 二、js逻辑代码 注&#xff1a;文档 https://developers.weixin.qq…...

新能源汽车智慧充电桩管理方案:新能源充电桩散热问题及消防安全监管方案

随着新能源汽车的快速普及&#xff0c;充电桩作为核心配套设施&#xff0c;其安全性与可靠性备受关注。然而&#xff0c;在高温、高负荷运行环境下&#xff0c;充电桩的散热问题与消防安全隐患日益凸显&#xff0c;成为制约行业发展的关键瓶颈。 如何通过智慧化管理手段优化散…...

HashMap中的put方法执行流程(流程图)

1 put操作整体流程 HashMap 的 put 操作是其最核心的功能之一。在 JDK 1.8 及以后版本中&#xff0c;其主要逻辑封装在 putVal 这个内部方法中。整个过程大致如下&#xff1a; 初始判断与哈希计算&#xff1a; 首先&#xff0c;putVal 方法会检查当前的 table&#xff08;也就…...

iOS性能调优实战:借助克魔(KeyMob)与常用工具深度洞察App瓶颈

在日常iOS开发过程中&#xff0c;性能问题往往是最令人头疼的一类Bug。尤其是在App上线前的压测阶段或是处理用户反馈的高发期&#xff0c;开发者往往需要面对卡顿、崩溃、能耗异常、日志混乱等一系列问题。这些问题表面上看似偶发&#xff0c;但背后往往隐藏着系统资源调度不当…...