百度360必应搜狗淘宝本站头条
当前位置:网站首页 > 热门文章 > 正文

记一次字符串末尾空白丢失的排查 → MySQL 是会玩的!

bigegpt 2024-10-12 05:47 6 浏览

开心一刻

  今天答应准时回家和老婆一起吃晚饭,但临时有事加了会班,回家晚了点

  回到家,本以为老婆会很生气,但老婆却立即从厨房端出了热着的饭菜

  老婆:还没吃饭吧,去洗下,来吃饭吧

  我洗好,坐下吃饭,内心感动十分;老婆坐旁边深情的看着我

  老婆:你知道谁最爱你吗

  我毫不犹豫道:你

  老婆:谁最关心你?

  我:你

  老婆:我是谁呀?

  我:我老婆

  老婆:那你以后是不是得对我好点?

  这时电话响了,一看好哥们打过来的,我接了并开了免提

  哥们:楼下洗浴八折,干啥呢?

  我:那个......,在陪我前妻吃口饭

问题背景

  一天,小伙伴找到我,他说他碰到一个很奇怪的问题

  他说:明明表名的入参是 test ,为什么展示到界面的记录包括 test 这条记录?

  他补充道:会不会是 MyBatis-Plus 做了什么骚操作,把 test 末尾的空格给拿掉了

  我:你直接把 SQL 语句到 MySQL 执行下试试

  结果如下:

  这看起来不够直观,我移动下光标

  然后我和小伙伴面面相觑

环境准备

   MySQL5MySQL8 各准备一个

  我们来看下默认情况下,末尾空白的判断情况

   MySQL 5.7.36 如下

  1 表示 TRUE ,也就是相等

   MySQL 8.0.27 如下

  0 表示 FALSE ,表示不相等

  这是什么原因,我们继续往下看

字符集与字符序

  比较肯定就需要比较规则, SQL 的比较规则就离不开字符序,字符序又与字符集相关,所以我们一个一个来捋

  字符集

  关于字符集,不是只言片语可以说清楚的,但是大家也不用担心,网上相关资料已经非常多,大家擦亮慧眼去查阅即可

  简单点来说:字符集定义了字符和字符的编码

  有人又问了:字符、字符的编码又是什么?

  为了方便大家理解,举个简单栗子

    有四个字符:A、B、C、D,这四个字符的编码分别是 A = 0, B = 1, C = 2, D = 3

    这里的字符(A、B、C、D) + 编码(0、1、2、3)就构成了字符集(character set)

   MySQL 支持的字符集有很多,可以通过 SHOW CHARACTER SET; 查看

   Charset :字符集名

   Description :描述

   Default collation :默认字符序

   Maxlen :每个字符最多字节数

  字符序

  定义了字符的比较规则;字符间的比较按何种规则进行

  一个字符集对应多个字符序,通过 SHOW COLLATION; 可以查看全部的字符序;也可以带条件查具体某个字符集的字符序

   Default 等于 Yes 表示是默认字符序

  每个字符集都有默认的字符序

  server的字符集与字符序

  当我们创建数据库时,没有指定字符集、字符序,那么server字符集、server字符序就会作为该数据库的字符集、字符序

  database的字符集与字符序

  指定数据库级别的字符集、字符序

  同一个MySQL服务下的数据库,可以分别指定不同的字符集、字符序

  创建、修改数据库的时候,可以通过 CHARACTER SETCOLLATE 指定数据库的字符集、字符序

  可以通过

  查看数据库的字符集和字符序

  table的字符集与字符序

  创建、修改表的时候,可以通过 CHARACTER SETCOLLATE 指定表的字符集、字符序

  可以通过

  查看表的字符序

  column的字符集与字符序

  类型为 CHARVARCHARTEXT 的列,可以指定字符集、字符序

  可以通过

  查看字段的字符集和字符序

  多个维度指定字符集、字符序的话,粒度越细的优先级越高( column > table > database > server

  如果细粒度未指定字符集、字符序,那么会继承上一级的字符集,字符序则是上一级字符集的默认字符序

  通常情况下我们一般不会指定 tablecolumn 粒度的字符集、字符序

  也就是说,通常情况下 column 的字符集会与 database 的字符集一致,而 column 的字符序则是 database 字符集的默认字符序

空白丢失

  上面讲了那么多,跟空白丢失有什么关系?

  大家先莫急,继续往下看

   MySQL5.7 The CHAR and VARCHAR Types中有这么一段

  翻译过来就是:

    1、类型是 CHARVARCHARTEXT 列的值,会根据列的字符序来比较和排序

    2、所有 MySQL 排序规则的类型都是 PAD SPACE 。这就意味着, CHARVARCHARTEXT 类型的值进行比较时,不用考虑任何末尾空格,LIKE 除外

    3、不受 SQL mode 影响,也就是说不管是严格模式,还是非严格模式,都不影响 2 所说的规则

  划重点,记笔记:在 MySQL5.7 及以下( <=5.7 )版本中,排序规则都是 PAD SPACE ,末尾的空格会忽略不考虑

  那如何让末尾空格参与比较了,有三种处理方式

  1、 BINARY ,类似 SELECT 'test' = BINARY 'test ';

  2、 LIKE ,类似 SELECT 'test' LIKE 'test ';

  3、 LENGTH 函数,类似

   MySQL8 做了调整,The CHAR and VARCHAR Types 有如下说明

  翻译过来就是:

    1、类型是 CHARVARCHARTEXT 列的值,会根据列的字符序来比较和排序

    2、 MySQL 字符序的 pad 参数的可选值,除了 PAD SPACE ,还增加了 NO PAD

    3、对于非二进制字符串( CHARVARCHARTEXT ),字符序 pad 参数决定如何去处理字符串末尾的空格

       NO PAD 不会忽略末尾空格,会将其当做其他字符一样对待

       PAD SPACE 会忽略末尾空格, LIKE 除外

       SQL mode 不参与字符串末尾空格的处理

   MySQL8 server 维度的字符集是 utf8mb4 ,对应的默认字符序是: utf8mb4_0900_ai_ci

   Pad_attribute 的值是 NO PAD ,也就是不会忽略字符串末尾的空格

  所以在 MySQL8 中, SELECT 'test' = 'test '; 默认情况下得到的结果是 0

总结

  1、非二进制字符串( CHARVARCHARTEXT )比较时,末尾空格的处理跟列的字符序有直接关系

  2、 MySQL5.7 及之前的版本,排序规则的类型都是 PAD SPACE ,会忽略字符串末尾的空格, LIKE 除外

  3、 MySQL8 开始,字符序增加了一个参数 Pad_attribute ,该参数的值不同,对字符串末尾空格的处理方式不同

     NO PAD :字符串末尾的空格会和其他字符一样,不会被忽略

     PAD SPACE :字符串末尾的空格会被忽略, LIKE 除外

  4、如上针对的都是非二进制字符串的排序和比较,而不是储存

原文链接:https://www.cnblogs.com/youzhibing/p/17384635.html

相关推荐

得物可观测平台架构升级:基于GreptimeDB的全新监控体系实践

一、摘要在前端可观测分析场景中,需要实时观测并处理多地、多环境的运行情况,以保障Web应用和移动端的可用性与性能。传统方案往往依赖代理Agent→消息队列→流计算引擎→OLAP存储...

warm-flow新春版:网关直连和流程图重构

本期主要解决了网关直连和流程图重构,可以自此之后可支持各种复杂的网关混合、多网关直连使用。-新增Ruoyi-Vue-Plus优秀开源集成案例更新日志[feat]导入、导出和保存等新增json格式支持...

扣子空间体验报告

在数字化时代,智能工具的应用正不断拓展到我们工作和生活的各个角落。从任务规划到项目执行,再到任务管理,作者深入探讨了这款工具在不同场景下的表现和潜力。通过具体的应用实例,文章展示了扣子空间如何帮助用户...

spider-flow:开源的可视化方式定义爬虫方案

spider-flow简介spider-flow是一个爬虫平台,以可视化推拽方式定义爬取流程,无需代码即可实现一个爬虫服务。spider-flow特性支持css选择器、正则提取支持JSON/XML格式...

solon-flow 你好世界!

solon-flow是一个基础级的流处理引擎(可用于业务规则、决策处理、计算编排、流程审批等......)。提供有“开放式”驱动定制支持,像jdbc有mysql或pgsql等驱动,可...

新一代开源爬虫平台:SpiderFlow

SpiderFlow:新一代爬虫平台,以图形化方式定义爬虫流程,不写代码即可完成爬虫。-精选真开源,释放新价值。概览Spider-Flow是一个开源的、面向所有用户的Web端爬虫构建平台,它使用Ja...

通过 SQL 训练机器学习模型的引擎

关注薪资待遇的同学应该知道,机器学习相关的岗位工资普遍偏高啊。同时随着各种通用机器学习框架的出现,机器学习的门槛也在逐渐降低,训练一个简单的机器学习模型变得不那么难。但是不得不承认对于一些数据相关的工...

鼠须管输入法rime for Mac

鼠须管输入法forMac是一款十分新颖的跨平台输入法软件,全名是中州韵输入法引擎,鼠须管输入法mac版不仅仅是一个输入法,而是一个输入法算法框架。Rime的基础架构十分精良,一套算法支持了拼音、...

Go语言 1.20 版本正式发布:新版详细介绍

Go1.20简介最新的Go版本1.20在Go1.19发布六个月后发布。它的大部分更改都在工具链、运行时和库的实现中。一如既往,该版本保持了Go1的兼容性承诺。我们期望几乎所...

iOS 10平台SpriteKit新特性之Tile Maps(上)

简介苹果公司在WWDC2016大会上向人们展示了一大批新的好东西。其中之一就是SpriteKitTileEditor。这款工具易于上手,而且看起来速度特别快。在本教程中,你将了解关于TileE...

程序员简历例句—范例Java、Python、C++模板

个人简介通用简介:有良好的代码风格,通过添加注释提高代码可读性,注重代码质量,研读过XXX,XXX等多个开源项目源码从而学习增强代码的健壮性与扩展性。具备良好的代码编程习惯及文档编写能力,参与多个高...

Telerik UI for iOS Q3 2015正式发布

近日,TelerikUIforiOS正式发布了Q32015。新版本新增对XCode7、Swift2.0和iOS9的支持,同时还新增了对数轴、不连续的日期时间轴等;改进TKDataPoin...

ios使用ijkplayer+nginx进行视频直播

上两节,我们讲到使用nginx和ngixn的rtmp模块搭建直播的服务器,接着我们讲解了在Android使用ijkplayer来作为我们的视频直播播放器,整个过程中,需要注意的就是ijlplayer编...

IOS技术分享|iOS快速生成开发文档(一)

前言对于开发人员而言,文档的作用不言而喻。文档不仅可以提高软件开发效率,还能便于以后的软件开发、使用和维护。本文主要讲述Objective-C快速生成开发文档工具appledoc。简介apple...

macOS下配置VS Code C++开发环境

本文介绍在苹果macOS操作系统下,配置VisualStudioCode的C/C++开发环境的过程,本环境使用Clang/LLVM编译器和调试器。一、前置条件本文默认前置条件是,您的开发设备已...