MySQL中的通配符

1. 百分号%
内部工作原理:
  • 代表零个、一个或多个任意字符。
  • LIKE 'A%':MySQL会从索引(如果存在)中查找所有以 "A" 开头的记录。如果没有索引,则需要扫描整个表。
  • MySQL解析器将模式转换为可执行的形式,并利用索引来加速匹配过程(如果有合适的索引)。
性能影响与优化:
  • 索引 :为了提高查询效率,可以在经常用于模式匹配的列上创建索引。例如,对于username LIKE 'A%',可以在username列上创建前缀索引。
  • 避免全表扫描:尽量不要在模式的开头使用通配符,因为这会导致MySQL无法利用索引而进行全表扫描。
示例与应用场景:
  • 前缀匹配:查找以特定字符串开头的所有记录。

    复制代码
    SELECT * FROM users WHERE username LIKE 'A%';

    这条语句会返回所有以字母 "A" 开头的用户名。

  • 后缀匹配:查找以特定字符串结尾的所有记录。

    复制代码
    SELECT * FROM emails WHERE email LIKE '%@example.com';

    这条语句会返回所有电子邮件地址以 @example.com 结尾的用户。

  • 中间匹配:查找包含特定子串的所有记录。

    复制代码
    SELECT * FROM products WHERE description LIKE '%shirt%';

    这条语句会返回描述中包含单词 "shirt" 的所有产品。

注意事项:
  • 使用%可能导致全表扫描,尤其是在没有适当索引的情况下,这可能会影响性能。
  • 如果查询条件非常宽松(如LIKE '%'),将返回所有记录,相当于SELECT * FROM table
高级用法:
  • 组合通配符 :可以结合多个通配符来构建更复杂的模式。例如,LIKE 'A%B%'匹配以 "A" 开头并包含 "B" 的字符串。
  • 转义字符 :当需要匹配实际的百分号时,使用转义字符。例如,LIKE '100%' ESCAPE ''将匹配包含 "100%" 的字符串。
2. 下划线_
内部工作原理:
  • 每个下划线代表一个任意字符的位置,因此LIKE 'J_n'会查找以 "J" 开头,后面跟任意单个字符,然后是 "n" 的记录。
  • 下划线的行为类似于正则表达式中的点号.,但它仅匹配单个字符。
性能影响与优化:
  • 索引利用 :虽然_只匹配单个字符,但在某些情况下仍然可以利用索引。例如,LIKE '_a%'可以部分利用索引。
  • 限制使用:尽量减少下划线的数量,因为过多的下划线可能导致索引失效。
示例与应用场景:
  • 精确位置匹配:查找特定位置上的任意字符。

    复制代码
    SELECT * FROM users WHERE username LIKE 'J_n';

    这条语句会返回所有以 "J" 开头,中间有一个任意字符,然后是 "n" 的用户名(如 "John", "Jane")。

  • 多字符匹配:结合多个下划线来匹配固定长度的字符串。

    复制代码
    SELECT * FROM products WHERE code LIKE 'P___001';

    这条语句会返回所有产品代码为 "P" 开头,后面跟三个任意字符且最后四位是 "001" 的产品。

注意事项:
  • _仅匹配单个字符,因此它适用于需要对字符串长度进行严格控制的场景。
高级用法:
  • 固定长度匹配 :通过组合多个下划线来匹配固定长度的字符串。例如,LIKE '___'匹配恰好三个字符长的字符串。
3. 方括号[]和范围-
内部工作原理:
  • 在正则表达式中,方括号用于定义字符集合或范围。例如,[abc]匹配 'a'、'b' 或 'c' 中的一个字符;[a-z]匹配任何小写字母。
  • MySQL使用的是POSIX正则表达式引擎,它支持多种模式匹配功能。
性能影响与优化:
  • 正则表达式的代价 :正则表达式比简单的LIKE查询更复杂,因此性能可能较差。对于简单模式,优先考虑使用LIKE
  • 索引兼容性:正则表达式通常不能有效利用索引,除非模式非常具体(如以锚定开始/结束)。
示例与应用场景:
  • 字符集合匹配:查找包含特定集合内字符的记录。

    复制代码
    SELECT * FROM users WHERE username REGEXP '[abc]';

    这条语句会返回用户名中包含 'a'、'b' 或 'c' 中任意一个字符的用户。

  • 字符范围匹配:查找包含特定范围内字符的记录。

    复制代码
    SELECT * FROM products WHERE code REGEXP '[0-9]{4}';

    这条语句会返回产品代码中包含四个连续数字的产品。

注意事项:
  • 正则表达式功能强大但复杂,确保理解正则表达式的语法以避免错误。
  • 正则表达式的性能可能不如简单的LIKE操作,特别是在处理大量数据时。
高级用法:
  • 排除字符集 :使用[^...]来排除特定字符。例如,REGEXP '[^aeiou]'匹配不包含元音字母的字符串。
  • 复合条件 :结合其他正则表达式元素(如|*+等)来构建复杂的模式。
4. 脱字符^和美元符号$
内部工作原理:
  • 这些符号用于表示字符串的开始 (^) 和结束 ($)。例如,^admin匹配以 "admin" 开头的字符串;example.com$匹配以 "example.com" 结尾的字符串。
  • 锚定可以显著提高查询的准确性,因为它限定了匹配的位置。
性能影响与优化:
  • 索引利用 :当模式以^开始时,MySQL可以利用索引加速查询。同样,以$结束的模式也可以部分利用索引。
  • 提高效率:通过明确指定匹配位置,减少了不必要的遍历,提高了查询效率。
示例与应用场景:
  • 字符串开始匹配:查找以特定字符串开头的记录。

    复制代码
    SELECT * FROM users WHERE username REGEXP '^admin';

    这条语句会返回所有用户名以 "admin" 开头的用户。

  • 字符串结束匹配:查找以特定字符串结尾的记录。

    复制代码
    SELECT * FROM emails WHERE address REGEXP '@example.com$';

    这条语句会返回所有电子邮件地址以 @example.com 结尾的记录。

注意事项:
  • 确保正确转义特殊字符(如点号.),以免误将其解释为正则表达式中的通配符。
高级用法:
  • 多行模式 :在某些环境中,可以通过设置选项来使^$匹配每一行的开始和结束,而不仅仅是整个字符串。
  • 结合其他元素:与正则表达式的其他元素结合使用,创建更为精确的匹配规则。
5. 点号.
内部工作原理:
  • 点号在正则表达式中表示任意单个字符。例如,..匹配两个任意字符。
  • 它的行为类似于下划线_,但只能用于正则表达式中。
性能影响与优化:
  • 性能较低:由于其通用性,点号可能会导致较慢的查询性能,特别是当没有适当索引时。
  • 谨慎使用:尽量避免过度使用点号,尤其是在不需要的地方。
示例与应用场景:
  • 任意字符匹配:查找包含任意单个字符的位置。

    复制代码
    SELECT * FROM codes WHERE code REGEXP '..';

    这条语句会返回所有恰好两个字符长的代码。

注意事项:
  • 点号只能匹配单个字符,不能匹配换行符(除非启用了相应的正则表达式选项)。
高级用法:
  • 非贪婪匹配 :在支持的环境中,可以使用修饰符(如?)来实现非贪婪匹配。例如,.*?表示尽可能少地匹配任意字符。
6. 星号*和加号+
内部工作原理:
  • *表示前面的字符出现零次或多次;+表示一次或多次。
  • 这些量词使得正则表达式能够灵活地处理重复字符的情况。
性能影响与优化:
  • 贪婪匹配 :默认情况下,*+是贪婪的,这意味着它们会尽可能多地匹配字符。这可能会导致性能问题。
  • 非贪婪匹配 :在支持的环境中,可以通过添加?修饰符来实现非贪婪匹配,从而优化性能。
示例与应用场景:
  • 零次或多次匹配:查找包含零个或多个连续字符的记录。

    复制代码
    SELECT * FROM texts WHERE content REGEXP 'a*';

    这条语句会返回包含零个或多个连续 'a' 字符的内容。

  • 一次或多次匹配:查找至少包含一个特定字符的记录。

    复制代码
    SELECT * FROM texts WHERE content REGEXP 'a+';

    这条语句会返回包含至少一个 'a' 字符的内容。

注意事项:
  • *+是贪婪的,它们会尽可能多地匹配字符。如果需要非贪婪匹配,可以在某些环境中使用?修饰符(如a+?)。
高级用法:
  • 限定次数 :使用{n}{n,}{n,m}来精确控制匹配的次数。例如,a{3}匹配连续三个 'a' 字符。
7. 问号?
内部工作原理:
  • 表示前面的字符是可选的,即它可以出现0次或1次。
  • 这种灵活性允许构建更宽松的匹配规则。
性能影响与优化:
  • 非贪婪特性?是非贪婪的,它会尝试最小化匹配,这对于某些场景是有利的。
  • 简化逻辑 :使用?可以简化某些条件逻辑,特别是在处理可选字符时。
示例与应用场景:
  • 可选字符匹配:查找包含可选字符的记录。

    复制代码
    SELECT * FROM words WHERE word REGEXP 'colou?r';

    这条语句会返回包含 "color" 或 "colour" 的单词。

注意事项:
  • ?是非贪婪的,它会尝试最小化匹配。
高级用法:
  • 结合其他元素:与其他正则表达式元素结合使用,创建更复杂的模式。
8. 竖线|
内部工作原理:
  • 作为逻辑"或"运算符,|允许匹配多个模式之一。
  • 例如,red|blue匹配包含 "red" 或 "blue" 的字符串。
性能影响与优化:
  • 复杂度增加:随着竖线两边模式数量的增加,查询复杂度也会增加,可能会影响性能。
  • 优化选择:尽量减少竖线的使用,或者将其放在最有可能匹配的部分。
示例与应用场景:
  • 多模式匹配:查找符合多个模式之一的记录。

    复制代码
    SELECT * FROM colors WHERE name REGEXP 'red|blue';

    这条语句会返回颜色名为 "red" 或 "blue" 的记录。

注意事项:
  • 竖线两边的模式是独立的,不会相互影响。
高级用法:
  • 嵌套条件:可以将竖线与其他正则表达式元素嵌套使用,构建更为复杂的条件逻辑。
特殊情况:转义通配符
内部工作原理:
  • 使用转义字符(默认为反斜杠)告诉MySQL将通配符视为普通字符。
  • 例如,LIKE 'A%' ESCAPE ''将匹配包含 "A%" 的字符串,而不是以 "A" 开头的任意字符串。
性能影响与优化:
  • 转义字符的影响:转义字符本身不会显著影响性能,但过多的转义可能会降低可读性和维护性。
  • ESCAPE 关键字 :通过ESCAPE关键字可以灵活指定不同的转义字符,适应不同的需求。
示例与应用场景:
  • 转义 %

    复制代码
    SELECT * FROM users WHERE username LIKE 'A%' ESCAPE '';

    这条语句将会查找所有以 "A%" 开头的用户名,其中的百分号被视为普通字符而非通配符。

  • 转义 _

    复制代码
    SELECT * FROM codes WHERE code LIKE '__123' ESCAPE '_';

    这条语句将会查找所有以下划线开头,后面跟 _123 的代码,注意这里使用了双下划线进行转义。

注意事项:
  • 当转义字符本身出现在查询中时,你需要再次转义它(例如,使用\来表示单个反斜杠)。
  • 使用ESCAPE关键字可以灵活指定不同的转义字符,从而适应不同的需求。
高级用法:
  • 多重转义 :当转义字符本身出现在查询中时,需要再次转义。例如,使用\来表示单个反斜杠。
  • 特殊字符处理:确保正确处理特殊字符(如空格、标点符号等),以避免意外的匹配结果。
最佳实践与注意事项:
  • 索引策略:对于频繁使用的模式匹配查询,考虑创建适当的索引(如前缀索引)。这可以极大地提高查询效率。
  • 避免不必要的通配符:尽量减少通配符的使用,特别是避免在模式的开头使用通配符,因为这通常会导致全表扫描。
  • 选择合适的工具:当涉及到复杂的模式匹配时,评估是否正则表达式是最佳选择,还是可以通过其他方式(如全文索引)实现更好的性能。
  • 测试与分析:在生产环境中实施之前,务必对查询进行充分的测试和性能分析,确保其符合预期。
相关推荐
gameboy0311 小时前
MySQL:基础操作(增删查改)
数据库·mysql·oracle
yoyo_zzm2 小时前
MySQL的索引
android·数据库·mysql
未来龙皇小蓝2 小时前
【MySQL-索引调优】06:最左匹配原则及优化
数据库·mysql·oracle·性能优化
一个有温度的技术博主2 小时前
Redis系列三:在linux上安装Redis
linux·数据库·redis
changhong19862 小时前
redis批量删除namespace下的数据
数据库·redis·缓存
IvorySQL2 小时前
PostgreSQL 技术日报 (3月18日)|从 MD5 到 SCRAM:PG 的安全转变
数据库·postgresql·开源
代码派2 小时前
MySQL 慢 SQL 排查这件事,NineData 社区 VS DBeaver/ Navicat 技术分析
数据库·sql·mysql·navicat·数据库管理工具·dbeaver·数据库对比
荧光点星2 小时前
MySQL DQL小结与DCL
sql·mysql
白菜!!!3 小时前
SQL中IF、IFNULL、NULLIF、ISNULL函数的使用
数据库·sql·mysql