replace() 是字符串函数,需配合 update 或 select 使用,严格逐字替换、区分大小写、支持重复替换,不支持正则;批量更新必须用 update 语句并加 where 条件,否则全表更新风险高。

MySQL REPLACE() 函数怎么用?直接替换字段里的子串
它不是用来批量更新数据的命令,而是一个字符串函数,必须配合 UPDATE 或 SELECT 使用。单独写 REPLACE('abc', 'a', 'x') 只返回结果,不会改表。
常见错误是以为 REPLACE() 能像正则那样模糊匹配,其实它只做**严格、逐字、从左到右**的字面量替换,不支持通配符或模式。
-
REPLACE(str, from_str, to_str):三个参数缺一不可,from_str为空字符串时,整条语句会返回空(不是原字符串) - 区分大小写,取决于字段的 collation;如果字段是
utf8mb4_0900_as_cs就区分,utf8mb4_general_ci则不区分 - 会重复替换:比如
REPLACE('aaaa', 'aa', 'x')结果是'xx',因为第一次替换了前两个a,剩下两个再被替换一次
想批量更新某列中的字符串,必须搭配 UPDATE
很多人写了 REPLACE(col, 'old', 'new') 就以为完成了,结果发现表没变——因为没执行 UPDATE。
正确写法是:
MySQL 9.6.0是面向Linux平台的2026年创新版本,核心架构迎来重大革新。其将外键约束与级联操作从InnoDB引擎层上移至SQL层,确保所有数据变更均被完整记录至Binlog,彻底解决了CDC(变更数据捕获)与主从复制中的数据不一致难题。此外,该版本引入container_aware启动选项以原生适配容器环境,并对审计日志进行了组件化重构,为追求极致数据一致性与云原生体验的开发者提供了全新选择。
UPDATE users SET name = REPLACE(name, 'Mr.', 'Miss.') WHERE name LIKE '%Mr.%';
注意加上 WHERE 条件,否则全表扫描+全量更新,小表无所谓,大表可能锁表几秒甚至更久。
- 没加
WHERE导致意外覆盖:比如把所有email字段里带@的都替换成别的,实际只想改某个域名 -
REPLACE()在UPDATE中属于表达式计算,不能用在WHERE左侧做索引字段的条件(如WHERE REPLACE(title, ' ', '') = 'abc'无法走索引) - 如果要替换内容含单引号,记得转义:
REPLACE(content, '''', ''')
和 REGEXP_REPLACE() 的关键区别在哪?
MySQL 8.0+ 才有 REGEXP_REPLACE(),它支持正则,而 REPLACE() 完全不支持。别指望用 REPLACE() 去删掉“多个连续空格”或者“开头的数字”,它做不到。
例如想把 ' 123 abc ' 清成 'abc':
-
REPLACE()搞不定:你不知道空格有几个,也不能跳过数字只留字母 -
REGEXP_REPLACE(str, '^[0-9 ]+|[ ]+$', '')可以,但要注意 MySQL 正则语法较弱,不支持懒惰匹配、反向引用等高级特性 - 低版本 MySQL(REGEXP_REPLACE() 都没有,只能靠应用层处理或升级
性能和安全容易被忽略的点
REPLACE() 是逐行计算的,字段越长、匹配子串越多,CPU 消耗越高。线上大表执行前最好先 EXPLAIN 看执行计划,确认走了索引(靠 WHERE 条件),而不是全表扫描。
- 别在
ORDER BY或GROUP BY里用REPLACE(),会导致无法使用索引,排序变慢 - 如果替换后长度超过字段定义(比如
VARCHAR(10)原来存'abc',替换成'xxxxxxxxxx'没问题,但换成'xxxxxxxxxxx'就会被截断,且不报错(除非开了 strict mode) - 事务中执行大量
REPLACE()更新,注意 binlog 日志体积会明显增大,主从延迟风险上升










