MySQL字符串比较忽略尾随空格

问题

今天遇到一个线上问题,排查过程中发现,MySQL 查询条件使用字符串判断等时会自动忽略字符串尾部的空格,示例如下:

MySQL 表格结构:

mysql 复制代码
CREATE TABLE `users` (
  `id` int(11) NOT NULL,
  `name` varchar(50) DEFAULT NULL,
  `age` int(11) DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;

新增数据,注意 name 传的是 "AAA ",尾部两个空格:

mysql 复制代码
INSERT INTO `test1`.`users`(`id`, `name`, `age`) VALUES (1, 'AAA  ', 30);

当执行查询操作时,竟然查出了数据:

mysql 复制代码
SELECT name, LENGTH(`name`) from users where name = 'AAA';

又试了当条件中空格在右时,可以匹配到数据:

当条件中空格在左时,又匹配不到数据:

原来,MySQL 在进行字符串比较时,默认情况下是对空格不敏感的,这与 MySQL 的 SQL 模式设置有关。

当使用=进行字符串比较时,如果字符串右侧包含空格,MySQL 会自动忽略这些空格。也就是说,在默认的 MySQL 配置下,'AAA''AAA ' 被认为是相等的。因此,在执行查询时:

sql 复制代码
SELECT name, LENGTH(`name`) FROM users WHERE name = 'AAA';

可以查到存储在数据库中 name = 'AAA ' 的数据。这是因为MySQL在比较时忽略了尾随空格。

为什么会这样?

MySQL 在进行字符串比较时遵循以下规则:

  1. 对于 CHAR 类型字段,存储时会自动删除尾随空格。
  2. 对于 VARCHAR 类型字段,在比较时会忽略尾随空格。

这种行为是因为 SQL 标准允许在字符串比较中忽略尾随空格。

如何避免这个问题?

如果你需要严格区分尾随空格,可以使用以下方法:

  1. 使用二进制比较 :可以使用BINARY关键字进行严格比较。

    sql 复制代码
    SELECT name, LENGTH(`name`) FROM users WHERE BINARY name = 'AAA';

    这样,MySQL会按照二进制字节逐个比较,尾随空格也不会被忽略。

  2. 使用LIKE进行精确匹配

    sql 复制代码
    SELECT name, LENGTH(`name`) FROM users WHERE name LIKE 'AAA';

    LIKE运算符在处理尾随空格时也会更严格。

  3. 显式地处理空格 :可以通过TRIM函数显式去掉空格后再进行比较:

    sql 复制代码
    SELECT name, LENGTH(`name`) FROM users WHERE TRIM(name) = 'AAA';

总结

MySQL默认在字符串比较中忽略尾随空格,如果需要进行严格匹配,可以使用BINARYLIKE或者显式处理空格的方法。

相关推荐
疯狂打码的少年3 分钟前
【数据库技术】SQL概述与数据定义(DDL:CREATE/DROP/ALTER)
数据库·笔记·sql·oracle
数据库小学妹16 分钟前
关系型数据库内置图查询来了:SQL/PGQ标准怎么用
数据库·图数据库·关系型数据库·图查询·数据库新特性
pnoker34 分钟前
IoT DC3 时序存储选型:四款数据库可插拔
数据库·物联网·postgresql·时序数据库·influxdb·tdengine·iotdb
黑臂麒麟1 小时前
HarmonyOS鸿蒙实战应用6:随手账本——Preferences本地持久化
数据库·华为·app·鸿蒙
2601_962174171 小时前
小试牛刀-SpringBoot集成SOL链
数据库·spring boot·后端
如何取名1 小时前
结合实际业务进行LRU淘汰算法优化设计(数据库开发日志)
数据库·算法
HanhahnaH1 小时前
Outbox 投递器:事务性发件箱模式详解
数据库
新时代牛马1 小时前
epoll 源码路径:从epoll_ctl 到ep_poll 的就绪唤醒
网络·数据库·网络协议
小蒜学长1 小时前
基于SpringBoot + Vue的智能健身房管理系统的设计与实现(代码+数据库+LW)
java·数据库·vue.js·spring boot·后端