LIKE 模式匹配(SQL 標準)
| 通配符 | 含義 | 範例 | 匹配範例 |
% | 任意長度字串(含 0 字元) | name LIKE 'Zhang%' | Zhang、ZhangSan、Zhang123 |
_ | 單一字元 | name LIKE 'Zh_ng' | Zhang、Zheng、Zhong |
常用 LIKE 範例
-- 以 'b' 開頭
SELECT * FROM pet WHERE name LIKE 'b%';
-- 以 'fy' 結尾
SELECT * FROM pet WHERE name LIKE '%fy';
-- 包含 'w'
SELECT * FROM pet WHERE name LIKE '%w%';
-- 正好 5 個字元
SELECT * FROM pet WHERE name LIKE '_____';
-- 逃脫字元(搜尋實際 % 或 _)
SELECT * FROM pet WHERE name LIKE '%\%%' ESCAPE '\';
重要特性
- MySQL 預設不區分大小寫(依照排序規則,如
utf8mb4_general_ci)
- 區分大小寫:
name LIKE 'b%' COLLATE utf8mb4_bin
- 索引優化:
% 不在開頭時可用索引(name LIKE 'Zhang%'),開頭有 % 則全表掃描
REGEXP 正則表達式(MySQL 擴展)
| 元字元 | 含義 | 範例 |
. | 任意單一字元 | 'a.c' 匹配 'abc', 'aXc' |
[...] | 字元類別 | '[abc]' 匹配 a/b/c |
[^...] | 排除字元類別 | '[^0-9]' 非數字 |
* | 前面元素 0 次或多次 | 'ab*c' 匹配 'ac', 'abc', 'abbc' |
+ | 前面元素 1 次或多次 | 'ab+c' 匹配 'abc', 'abbc' |
? | 前面元素 0 或 1 次 | 'ab?c' 匹配 'ac', 'abc' |
{n} | 前面元素恰好 n 次 | 'a{3}' 匹配 'aaa' |
^ | 字串開頭 | '^Zhang' 以 Zhang 開頭 |
$ | 字串結尾 | 'San$' 以 San 結尾 |
| | 或邏輯 | 'cat|dog' 匹配 cat 或 dog |
(...) | 分組 | '(ab)+' 匹配 'ab', 'abab' |
REGEXP 實戰範例
-- 以 b/B 開頭
SELECT * FROM pet WHERE name REGEXP '^[bB]';
-- 以 fy/FY 結尾
SELECT * FROM pet WHERE name REGEXP '[fF][yY]$';
-- 包含 w/W
SELECT * FROM pet WHERE name REGEXP '[wW]';
-- 正好 5 個字元
SELECT * FROM pet WHERE name REGEXP '^.....$';
-- 或
SELECT * FROM pet WHERE name REGEXP '^.{5}$';
-- 僅含字母數字
SELECT * FROM pet WHERE name REGEXP '^[a-zA-Z0-9]+$';
-- 手機號格式(簡化)
SELECT * FROM users WHERE phone REGEXP '^1[3-9][0-9]{9}$';
-- Email 簡易驗證
SELECT * FROM users WHERE email REGEXP '^[^@]+@[^@]+\.[^@]+$';
REGEXP 進階特性
- 預設區分大小寫,用字元類別
[aA] 或 COLLATE utf8mb4_general_ci 忽略大小寫
- 任何位置匹配即成功(不像 LIKE 需匹配整個值),故不需兩側加
.*
- MySQL 8.0+ 支援
REGEXP_REPLACE()、REGEXP_SUBSTR()、REGEXP_INSTR()
效能與選型建議
| 場景 | 推薦 | 理由 |
| 前綴匹配 | LIKE 'prefix%' | 可用索引、最快 |
| 後綴/包含匹配 | LIKE '%suffix' | 全掃描,考慮全文索引 |
| 複雜格式驗證 | REGEXP | 表達力強、可維護 |
| 資料清洗/抽取 | REGEXP_SUBSTR (8.0+) | 原生支援,無需應用層處理 |
| 大小寫不敏感 | LIKE + ci 排序規則 | 比 REGEXP 字元類別更簡潔 |
全文索引替代方案
大量文本搜尋建議使用 Full-Text Search:
ALTER TABLE articles ADD FULLTEXT INDEX ft_content (content);
SELECT * FROM articles WHERE MATCH(content) AGAINST('MySQL 優化' IN NATURAL LANGUAGE MODE);