0
点赞
收藏
分享

微信扫一扫

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

开心一刻

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

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

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

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

  老婆:你知道谁最爱你吗

  我毫不犹豫道:你

  老婆:谁最关心你?

  我:你

  老婆:我是谁呀?

  我:我老婆

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

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

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

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

问题背景

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

test  ,为什么展示到界面的记录包括 test

MyBatis-Plus 做了什么骚操作,把 test

SQL 语句到 MySQL

  结果如下:

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

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

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

  然后我和小伙伴面面相觑

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

环境准备

MySQL5 、 MySQL8

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

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

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

MySQL 5.7.36

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

TRUE

MySQL 8.0.27

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

FALSE

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

字符集与字符序

SQL

  字符集

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

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

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

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

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

    有四个字符: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;

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

Charset

Description

Default

Maxlen

  字符序

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

SHOW COLLATION;

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

Default 等于 Yes

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

  server的字符集与字符序

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

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

  database的字符集与字符序

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

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

CHARACTER SET 、  COLLATE

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

  可以通过

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

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

  table的字符集与字符序

CHARACTER SET 、 COLLATE

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

  可以通过

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

  查看表的字符序

  column的字符集与字符序

CHAR 、 VARCHAR 、 TEXT

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

  可以通过

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

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

column > table > database > server

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

table 、 column

column 的字符集会与 database 的字符集一致,而 column 的字符序则是 database

空白丢失

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

  大家先莫急,继续往下看

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

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

  翻译过来就是:

CHAR 、 VARCHAR 、 TEXT

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

SQL mode

划重点,记笔记:在 MySQL5.7 及以下( <=5.7 )版本中,排序规则都是 PAD SPACE

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

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

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

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

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

LENGTH

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

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

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

  翻译过来就是:

CHAR 、 VARCHAR 、 TEXT

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

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

CHAR 、 VARCHAR 、 TEXT ),字符序 pad

NO PAD

PAD SPACE 会忽略末尾空格, LIKE

SQL mode

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

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

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

Pad_attribute 的值是 NO PAD

MySQL8 中, SELECT 'test' = 'test ';

总结

CHAR 、 VARCHAR 、 TEXT

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

MySQL8 开始,字符序增加了一个参数 Pad_attribute

NO PAD

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

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

参考

  The CHAR and VARCHAR Types

  The CHAR and VARCHAR Types

  再见乱码:5分钟读懂MySQL字符集设置



举报

相关推荐

0 条评论