SQL LIKE 操作符(千字长文)
💡一则或许对你有用的小广告
欢迎加入小哈的星球 ,你将获得:专属的项目实战 / 1v1 提问 / Java 学习路线 / 学习打卡 / 每月赠书 / 社群讨论
- 新项目:《从零手撸:仿小红书(微服务架构)》 正在持续爆肝中,基于
Spring Cloud Alibaba + Spring Boot 3.x + JDK 17...
,点击查看项目介绍 ;- 《从零手撸:前后端分离博客项目(全栈开发)》 2 期已完结,演示链接: http://116.62.199.48/ ;
截止目前, 星球 内专栏累计输出 82w+ 字,讲解图 3441+ 张,还在持续爆肝中.. 后续还会上新更多项目,目标是将 Java 领域典型的项目都整一波,如秒杀系统, 在线商城, IM 即时通讯,权限管理,Spring Cloud Alibaba 微服务等等,已有 2900+ 小伙伴加入学习 ,欢迎点击围观
前言:SQL LIKE 操作符的核心作用与应用场景
在数据库查询的世界中,精确匹配固然重要,但很多时候我们需要处理模糊的、不完全确定的搜索需求。例如,用户可能希望找到名字中包含“John”的所有客户,或者订单编号以“2023”开头的记录。这时,SQL 的 LIKE
操作符便成为了解决这类问题的核心工具。它允许开发者通过通配符实现灵活的模式匹配,是 SQL 语言中不可或缺的“模糊查询利器”。
本文将从基础概念逐步深入,结合实际案例和代码示例,帮助编程初学者和中级开发者掌握 SQL LIKE 操作符
的核心用法,理解其性能优化技巧,并解决常见问题。
基础语法与通配符:如何用“模式”匹配数据
基本语法结构
LIKE
操作符的基本语法如下:
SELECT * FROM 表名 WHERE 列名 LIKE '模式';
其中,“模式”可以包含普通字符和通配符,用于定义需要匹配的字符串规则。例如:
SELECT * FROM users WHERE name LIKE 'J%';
这条语句会返回所有名字以字母“J”开头的用户记录。
通配符的魔法:% 和 _
SQL LIKE
主要使用两种通配符:
-
%
(百分号):代表任意数量的字符(包括零个字符)。- 比喻:想象
%
是一张无限伸缩的“寻宝图”,可以匹配任意长度的路径。 - 示例:
name LIKE 'Li%'
匹配所有以“Li”开头的名字,如“Lisa”、“Lily”或“Lionel”。
- 比喻:想象
-
_
(下划线):代表一个单一的任意字符。- 比喻:
_
就像一个“空位标记”,只能占一个位置,但可以是任何字符。 - 示例:
code LIKE '__2023'
匹配所有长度为 6 位且以“2023”结尾的代码,例如“AB2023”或“9X2023”。
- 比喻:
实战案例:模糊搜索用户信息
假设有一个 users
表,包含以下数据:
id | name | email
---|------------|-----------------
1 | Alice | alice@example.com
2 | Bob | bob123@domain.net
3 | Charlie | charlie456@site.org
4 | David | dave@company.com
以下查询将展示 LIKE
的不同用法:
-- 查找名字以 "A" 开头的用户
SELECT * FROM users WHERE name LIKE 'A%'; -- 返回 Alice
-- 查找邮箱以 "example.com" 结尾的用户
SELECT * FROM users WHERE email LIKE '%example.com'; -- 返回 Alice
-- 查找名字长度为5且第三个字符为 "a" 的用户(如 "Alice")
SELECT * FROM users WHERE name LIKE '__a%'; -- 返回 Alice("Al" + "i" + ...)
进阶技巧:NOT LIKE 与复杂模式设计
反向匹配:NOT LIKE 的应用场景
当需要排除符合条件的记录时,可以使用 NOT LIKE
:
-- 查找邮箱不以 "example.com" 结尾的用户
SELECT * FROM users WHERE email NOT LIKE '%example.com';
组合通配符:构建更复杂的模式
通过组合 %
和 _
,可以实现更精细的匹配逻辑:
-- 查找名字中包含 "li" 的用户(不区分大小写,假设数据库默认是不区分的)
SELECT * FROM users WHERE name LIKE '%li%'; -- 返回 "Lisa", "Lily", "Charlie"(如果名字中有 "li")
-- 查找名字恰好为4个字符且第三个字符为 "a" 的用户
SELECT * FROM users WHERE name LIKE '__a_'; -- 返回 "Lily"(假设存在该记录)
性能优化:通配符位置与索引的“黄金法则”
通配符位置对查询速度的影响
LIKE
的性能取决于通配符的位置:
- 前缀模式(如
LIKE 'A%'
):
数据库可以利用索引快速定位以“A”开头的记录,类似通过书的目录直接找到章节。 - 后缀或中间模式(如
LIKE '%app'
或LIKE '%p%'
):
数据库无法有效使用索引,需逐行扫描,这在大数据量时会导致显著延迟,如同在图书馆中逐页翻书寻找关键词。
案例对比:不同模式的查询效率
假设有一个包含百万级订单的 orders
表:
-- 高效查询(使用前缀模式)
SELECT * FROM orders WHERE order_number LIKE 'ORD-2023%'; -- 可能快速返回结果
-- 低效查询(后缀模式)
SELECT * FROM orders WHERE description LIKE '%urgent%'; -- 可能需要数秒甚至更久
索引的“救命稻草”:全文搜索与特殊策略
对于频繁的模糊查询,可以考虑以下优化:
- 全文索引:某些数据库(如 MySQL 的
FULLTEXT
索引)专门优化文本搜索。 - 预处理字段:将需要模糊查询的字段(如
name
)的前缀单独存储,例如name_prefix
列存储前三个字符。 - 避免以
%
开头:若可能,调整业务逻辑以优先使用前缀模式。
常见问题与解决方案
问题1:大小写敏感性
默认情况下,LIKE
是否区分大小写取决于数据库配置。例如:
- MySQL 在默认配置下不区分大小写,但可通过
COLLATE
强制区分:SELECT * FROM users WHERE name LIKE 'a%' COLLATE utf8mb4_bin; -- 匹配严格以"A"开头
- PostgreSQL 默认区分大小写,需使用
ILIKE
实现不敏感匹配:SELECT * FROM users WHERE name ILIKE 'a%'; -- 不区分大小写
问题2:通配符本身的转义
当需要匹配 %
或 _
字符本身时,必须使用转义符。例如:
-- 查找包含 "10%" 的订单描述(假设转义符为反斜杠)
SELECT * FROM orders WHERE description LIKE '%10\%%' ESCAPE '\'; -- 匹配 "10% off" 等内容
问题3:多条件组合与优先级
使用 AND
或 OR
组合多个 LIKE
条件时,需注意运算符优先级:
-- 正确写法:使用括号明确逻辑
SELECT * FROM products
WHERE (name LIKE '%phone%') AND (price BETWEEN 500 AND 1000);
实战案例:构建一个模糊搜索功能
场景描述
假设需要为电商平台设计一个商品搜索功能,要求:
- 支持关键词模糊匹配商品名称。
- 允许用户输入通配符(如“%”)进行高级搜索。
- 提供价格范围筛选。
SQL 实现方案
-- 基础模糊搜索(注意转义用户输入的 % 和 _)
SELECT * FROM products
WHERE name LIKE '%' || :search_term || '%'
AND price BETWEEN :min_price AND :max_price
AND category = :category_id;
安全性建议
直接拼接用户输入可能导致 SQL 注入,应改用参数化查询(如预编译语句),例如在 Python 中:
cursor.execute(
"SELECT * FROM products WHERE name LIKE %s AND price BETWEEN %s AND %s",
('%' + search_term + '%', min_price, max_price)
)
结论:掌握模糊查询的艺术
通过本文的讲解,读者应该能够:
- 理解
SQL LIKE
的基本语法与通配符的使用逻辑。 - 设计高效的模糊查询策略,避免性能陷阱。
- 解决常见问题,如大小写敏感性和转义需求。
- 将理论应用到实际场景,如电商搜索功能的开发。
SQL LIKE
操作符如同一把双刃剑:它赋予开发者强大的模糊匹配能力,但也可能因不当使用导致性能问题。建议开发者始终遵循“前缀优先”原则,并结合索引优化查询效率。随着实践的深入,您将逐渐掌握在精确与模糊之间平衡的艺术,让数据库查询既灵活又高效。