mysql 8.0 支持 regexp_like 等正则函数,5.7 仅支持 regexp/rlike 运算符;8.0 函数可嵌入 select、order by、check 约束等上下文,支持 match_type 参数(如 'i' 'm'),且对 null 返回 false,而 5.7 中 regexp 对 null 返回 null,行为不兼容。

MySQL 8.0 支持 REGEXP_LIKE,MySQL 5.7 不支持——它只有 REGEXP 和 RLIKE 这两个布尔型操作符,没有独立的函数接口。
MySQL 5.7 只能用 REGEXP / RLIKE,不能写成函数调用形式
在 5.7 中,正则匹配只能作为 WHERE 条件里的运算符使用,语法是:
SELECT * FROM users WHERE name REGEXP '^A.*[0-9]$';
你不能把它当函数用,比如不能出现在 SELECT 列表、CASE WHEN 或子查询中直接取布尔值。常见错误包括:
- 写
SELECT REGEXP_LIKE(name, '...')→ 报错ERROR 1305 (42000): FUNCTION REGEXP_LIKE does not exist - 想在
ORDER BY里按是否匹配排序 → 必须改写为ORDER BY name REGEXP '...' DESC - 需要对多列联合做正则判断 → 得靠嵌套
IF(name REGEXP ... OR email REGEXP ..., 1, 0),可读性差
MySQL 8.0 的 REGEXP_LIKE 是标准 SQL 函数,参数更清晰
8.0 引入了符合 SQL:2008 标准的 REGEXP_LIKE 函数,签名是:
REGEXP_LIKE(expr, pat[, match_type])
其中 match_type 支持多个标志位组合(如 'c' 区分大小写、'i' 忽略大小写、'm' 多行模式),比 5.7 的 REGEXP 更可控。关键差异点:
-
REGEXP在 5.7 中默认行为受sql_mode影响(比如是否开启NO_BACKSLASH_ESCAPES),而REGEXP_LIKE行为更稳定 - 8.0 允许在生成列、检查约束(
CHECK)中直接使用REGEXP_LIKE,例如:ALTER TABLE users ADD COLUMN is_valid_email TINYINT AS (REGEXP_LIKE(email, '^[^@]+@[^@]+\.[^@]+$')) STORED; - 配合窗口函数或 CTE 使用更自然,比如:
SELECT name, REGEXP_LIKE(name, '^[A-Z]') AS starts_with_cap FROM users ORDER BY starts_with_cap;
性能上没本质提升,但写法优化能减少执行计划误判
REGEXP_LIKE 本身不比 REGEXP 快,底层引擎一样。真正影响性能的是写法是否利于优化器选择索引或提前剪枝:
- 避免在
REGEXP_LIKE(col, '.*abc.*')这类全模糊模式上建索引——和LIKE '%abc%'一样无法走索引 - 如果匹配逻辑固定(如校验手机号格式),8.0 可用生成列 + 索引加速:
ADD COLUMN phone_valid TINYINT AS (REGEXP_LIKE(phone, '^1[3-9]\d{9}$')) STORED, ADD INDEX idx_phone_valid (phone_valid); - 5.7 想实现类似效果,得靠触发器或应用层校验,容易漏或不一致
- 注意:MySQL 的正则引擎不支持回溯限制,复杂嵌套量词(如
(a+)+b)可能引发灾难性回溯,无论 5.7 还是 8.0 都要避开
迁移时最容易被忽略的兼容性坑
从 5.7 升级到 8.0 后,原有 REGEXP 语句大多能跑,但以下细节会悄悄出错:
-
REGEXP在 5.7 中对 NULL 值返回 NULL,而REGEXP_LIKE(NULL, '...')明确返回FALSE(不是 NULL),WHERE条件中行为不同 - 5.7 的
REGEXP对换行符处理较松散;8.0 的REGEXP_LIKE默认不跨行,加'm'才启用^/$匹配每行首尾 - 某些特殊字符转义规则微调,比如
\在字符串字面量中需写成\\才能在正则里表示单个反斜杠 - 如果你用 ORM(如 SQLAlchemy、MyBatis),确认其方言是否已适配 8.0 的
REGEXP_LIKE语法,否则可能生成无效 SQL
最麻烦的不是函数有没有,而是 NULL 处理和多行模式这种静默变更——它们不会报错,但结果可能和预期不一致。











