数据库LIKE查询屡试不爽?揭秘大多数人都忽视的秘密操作符!

往期推荐:

1. 问题背景

在某次数据库查询中,select * from sys_user where user_name LIKE concat( '%', '赵', '%' ) 能正确查询到包含"赵"的数据,而类似的条件 concat( '%', '赵小', '%' ) 却无法查询到"赵小强"。这一问题暴露了数据的隐藏异常。

通过 Hex() 函数进一步分析,发现"赵小强"的十六进制值为 E8B5B5E5B08FE5BCBA。然而,用 select hex(user_name) 查询时,结果包含了不可见的空白字符 E2808B。这些字符未被用户直观察觉,但干扰了 SQL 查询的匹配逻辑。


2. 不可见字符的影响与判定

不可见字符如 E2808B 是 Unicode 的零宽空白字符(Zero-Width Space),其存在通常由数据导入不规范或应用程序处理不当引起。这些字符对字符串显示无影响,但在计算机匹配时会导致异常行为,例如 SQL 查询失败。

通过进一步验证,问题可归因于零宽字符的存在。更新语句 UPDATE sys_user SET user_name = REPLACE(user_name, UNHEX('E2808B'), ''); 被提出用于移除这些字符。


3. 数据修复方法

针对上述问题,以下步骤被应用解决:

3.1 确认问题字符

使用 select hex(user_name) 查看目标字段的十六进制值,判定是否包含异常字符。

3.2 编写修复 SQL

利用 REPLACE() 函数结合 UNHEX() 替换掉指定不可见字符:

sql 复制代码
UPDATE sys_user SET user_name = REPLACE(user_name, UNHEX('E2808B'), '');

此语句逐行处理目标字段,将不可见字符替换为空字符串,从而修复数据。


4. 避免类似问题的建议

4.1 数据输入规范化

在数据导入或处理前,使用正则表达式过滤掉不可见字符,确保输入数据无异常。

4.2 数据校验机制

对关键字段定期运行十六进制检查,确保字段值符合预期格式,避免隐性问题。

4.3 字符串处理优化

在字符串操作函数中,明确考虑可能的隐藏字符,例如零宽空白符或其他控制字符。


5. 零宽空白字符

除了常见的零宽空白字符 E2808B(Zero-Width Space, U+200B),以下是其他常见的零宽字符及其特性:

零宽空格类字符

  • Zero Width Non-Joiner (U+200C) 用于防止两个字符连写,其十六进制表示为 E2808C
  • Zero Width Joiner (U+200D) 用于指示字符应连写,十六进制表示为 E2808D
  • Word Joiner (U+2060) 类似于零宽空格,但主要用于禁用断行,十六进制表示为 E281A0

格式控制字符

  • Left-to-Right Mark (U+200E) 用于标记文本方向为从左到右,十六进制表示为 E2808E
  • Right-to-Left Mark (U+200F) 用于标记文本方向为从右到左,十六进制表示为 E2808F
  • Left-to-Right Embedding (U+202A) 指定嵌套的从左到右文本方向,十六进制表示为 E280AA
  • Right-to-Left Embedding (U+202B) 指定嵌套的从右到左文本方向,十六进制表示为 E280AB
  • Pop Directional Formatting (U+202C) 结束嵌套方向设置,十六进制表示为 E280AC

其他不可见字符

  • Zero Width No-Break Space (U+FEFF) 原为字节顺序标记 (BOM),现作为零宽字符使用,十六进制表示为 EFBBBF
  • Soft Hyphen (U+00AD) 用于指示潜在的断字位置,但通常不显示,十六进制表示为 C2AD

COLLATE排序规则可能的影响

排序规则 (COLLATE) 定义了字符串比较和排序的规则,包括:

  • 大小写敏感性 :区分大小写的规则(如 _bin 排序规则)和不区分大小写的规则(如 _ci)。
  • 字符比较规则 :某些排序规则会将字符视为等价,比如带重音的字符(ée)在一些规则中可能被视为相同。

常见排序规则对 LIKE 的影响

以下是几种典型排序规则及其对 LIKE 的影响:

  • 大小写不敏感 (默认,如 utf8mb4_general_ciutf8mb4_unicode_ci): LIKE 'abc%' 将匹配 abc, Abc, ABC 等。
  • 大小写敏感 (如 utf8mb4_bin): LIKE 'abc%' 仅匹配大小写完全一致的 abc
  • 如果排序规则忽略重音(如 utf8mb4_general_ci),则 LIKE 'cafe%' 可能匹配 cafécafe。在 utf8mb4_bin 中,重音符号会被严格区分,因此 cafécafe 是不同的。

6. 总结

不可见字符如零宽空白符可能引发查询和匹配异常,问题解决需从排查、修复和预防三方面入手。

通过合理的技术手段,数据库的完整性和查询准确性得以保障,同时为避免类似问题提供了经验参考。

关于作者

来自全栈程序员nine的探索与实践,持续迭代中。(技术交流卫星codetrend)

相关推荐
流星白龙9 小时前
【Redis】2.Redis重大版本
数据库·redis·junit
流星白龙9 小时前
【Redis】7.Hash表
数据库·redis·哈希算法
流星白龙10 小时前
【Redis】4.基本全局命令
数据库·redis·缓存
王八八。11 小时前
Navicat 17破解版下载安装教程 附安装激活步骤(2026 最新版)
数据库·navicat
Jelena1577958579212 小时前
电商运营分析数据比价接口实战:多平台价格监控与智能决策系统
java·大数据·数据库
流星白龙13 小时前
【Redis】3.Redis安装与命令行客户端
数据库·redis·缓存
二宝哥14 小时前
MySQL 修改密码策略详解:从基础到高级配置
mysql·密码学
马优晨14 小时前
DBeaver 连接 MySQL 完整排错教程
mysql·dbeaver连接mysql·dbeaver连mysql·dbeaver连接数据库·db连接mysql
凌虚14 小时前
基于 PostgreSQL WAL 构建 CDC 系统:原理与工程实现
数据库·后端·postgresql
BullSmall14 小时前
PostgreSQL 14 pg_dumpall 完整备份指南
数据库·postgresql·oracle