下划线\_在LIKE中严格匹配且仅匹配一个任意非NULL字符,不跳过缺失位置;查字面下划线需用ESCAPE显式转义;与%组合时位置影响索引使用;多数据库语义基本一致但UTF-8、大小写、排序规则存在细微差异。

下划线 _ 在 LIKE 中的实际行为
_ 是 SQL 标准通配符,只匹配**一个且仅一个**任意字符(包括字母、数字、空格、标点,但不匹配 NULL)。它不是正则表达式里的 .,也不跳过缺失字符——如果目标字段该位置没字符,就完全不匹配。
常见误用是以为 _ 能“跳过可选部分”,比如想匹配 'a_c' 和 'ac',结果后者根本不会被命中,因为 _ 强制要求存在一个字符。
必须转义字面意义的下划线
如果你要查真实含下划线的字符串(比如用户名 'user_name'),直接写 WHERE name LIKE 'user_name' 会被当成 user + 任意单字符 + name,大概率查不到。
解决方法是显式指定转义字符,并在下划线前加它:
WHERE name LIKE 'user\_name' ESCAPE '\'
要点:
-
ESCAPE后的字符本身不能出现在待查字符串中,否则需双重转义 - 不同数据库默认转义符不同:MySQL 默认无转义,PostgreSQL 和 SQL Server 也需显式声明
- Oracle 支持
ESCAPE,但某些旧驱动可能忽略,建议统一显式写出
_ 和 % 混用时的位置与性能陷阱
_ 和 % 可组合,但顺序和数量直接影响索引使用和扫描范围:
-
LIKE 'a_b%':能用上前缀索引(如索引建在name上),因为前两个字符确定(a+ 任意1字符) -
LIKE '%a_b':无法走索引,必全表扫描 -
LIKE 'a__b':匹配a+ 任意两个字符 +b,长度固定,优化器可能更好估算行数
注意:_ 多了容易误匹配。例如 'A__B' 会匹配 'A B'(含空格)或 'A%B'(含百分号),只要长度对、位置对。
不同数据库对 _ 的细微差异
绝大多数 SQL 数据库(PostgreSQL、MySQL、SQL Server、Oracle)对 _ 的基础语义一致,但边界情况有区别:
- MySQL 8.0+ 在 utf8mb4 下,
_匹配一个utf8mb4字符(即一个 code point),不是字节;而老版本用utf8时可能按字节算,导致 emoji 或生僻字出错 - PostgreSQL 对大小写敏感:
'A_'不匹配'ab'(除非用ILIKE) - SQL Server 如果排序规则为
CI(case-insensitive),_自动忽略大小写;但若字段含补充字符(如某些 emoji),需确认排序规则是否支持
跨库迁移时,别只测 ASCII 场景——拿中文、emoji、带重音符号的字母实测一次,比看文档更可靠。

















