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 主要使用两种通配符:

  1. %(百分号):代表任意数量的字符(包括零个字符)。

    • 比喻:想象 % 是一张无限伸缩的“寻宝图”,可以匹配任意长度的路径。
    • 示例:name LIKE 'Li%' 匹配所有以“Li”开头的名字,如“Lisa”、“Lily”或“Lionel”。
  2. _(下划线):代表一个单一的任意字符。

    • 比喻:_ 就像一个“空位标记”,只能占一个位置,但可以是任何字符。
    • 示例: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 的性能取决于通配符的位置:

  1. 前缀模式(如 LIKE 'A%'):
    数据库可以利用索引快速定位以“A”开头的记录,类似通过书的目录直接找到章节。
  2. 后缀或中间模式(如 LIKE '%app'LIKE '%p%'):
    数据库无法有效使用索引,需逐行扫描,这在大数据量时会导致显著延迟,如同在图书馆中逐页翻书寻找关键词。

案例对比:不同模式的查询效率

假设有一个包含百万级订单的 orders 表:

-- 高效查询(使用前缀模式)
SELECT * FROM orders WHERE order_number LIKE 'ORD-2023%'; -- 可能快速返回结果

-- 低效查询(后缀模式)
SELECT * FROM orders WHERE description LIKE '%urgent%'; -- 可能需要数秒甚至更久

索引的“救命稻草”:全文搜索与特殊策略

对于频繁的模糊查询,可以考虑以下优化:

  1. 全文索引:某些数据库(如 MySQL 的 FULLTEXT 索引)专门优化文本搜索。
  2. 预处理字段:将需要模糊查询的字段(如 name)的前缀单独存储,例如 name_prefix 列存储前三个字符。
  3. 避免以 % 开头:若可能,调整业务逻辑以优先使用前缀模式。

常见问题与解决方案

问题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:多条件组合与优先级

使用 ANDOR 组合多个 LIKE 条件时,需注意运算符优先级:

-- 正确写法:使用括号明确逻辑
SELECT * FROM products 
WHERE (name LIKE '%phone%') AND (price BETWEEN 500 AND 1000);

实战案例:构建一个模糊搜索功能

场景描述

假设需要为电商平台设计一个商品搜索功能,要求:

  1. 支持关键词模糊匹配商品名称。
  2. 允许用户输入通配符(如“%”)进行高级搜索。
  3. 提供价格范围筛选。

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)
)

结论:掌握模糊查询的艺术

通过本文的讲解,读者应该能够:

  1. 理解 SQL LIKE 的基本语法与通配符的使用逻辑。
  2. 设计高效的模糊查询策略,避免性能陷阱。
  3. 解决常见问题,如大小写敏感性和转义需求。
  4. 将理论应用到实际场景,如电商搜索功能的开发。

SQL LIKE 操作符如同一把双刃剑:它赋予开发者强大的模糊匹配能力,但也可能因不当使用导致性能问题。建议开发者始终遵循“前缀优先”原则,并结合索引优化查询效率。随着实践的深入,您将逐渐掌握在精确与模糊之间平衡的艺术,让数据库查询既灵活又高效。

最新发布