MySQL搜索英文执行LIKE查询时c被识别为ç返回异常拉丁字符结果
问题相关代码
Laravel业务代码:
MedicalTerms::where('term','like','%hce%')->get();
框架生成的原生SQL:
SELECT * FROM medical_terms WHERE term like '%hce%'
异常现象:模糊搜索英文字符串hce时,返回了包含特殊字符ç的hçe相关结果,与预期的0条返回不符。
查询结果示例截图
核心原因
该现象和Laravel框架无关,是数据库字段的**排序规则(Collation)**配置导致的。
你当前medical_terms表term字段使用的是口音不敏感(Accent Insensitive)的排序规则,国内最常用的utf8mb4_general_ci、utf8mb4_unicode_ci都属于这类规则:这类规则设计初衷是适配多语言自然搜索场景,会将同源拉丁字符的变音版本和基础英文字符判定为等价,比如:
c等价于ç、ć、ča等价于á、à、ä、âo等价于ó、ò、ö、ô
在做等值匹配、LIKE模糊匹配时,上述等价字符都会被命中,因此会出现普通c匹配到软音符ç的情况。
修复方案
根据业务需求二选一即可:
- 全局严格区分变音字符
直接修改term字段的排序规则为口音敏感(Accent Sensitive)版本,比如MySQL 8.0+推荐使用utf8mb4_0900_as_cs,低版本可以选utf8mb4_unicode_as_cs,其中_as后缀代表口音敏感、_cs后缀代表大小写敏感。修改后所有默认查询都会严格区分基础字符和变音字符,不会再出现跨字符匹配的问题。 - 仅单条查询需要严格匹配,不修改表结构
在查询语句中临时强制指定口音敏感的排序规则即可,不需要改动原有表配置:
原生SQL写法:
Laravel对应写法:SELECT * FROM medical_terms WHERE term LIKE '%hce%' COLLATE utf8mb4_unicode_as_csMedicalTerms::whereRaw('term LIKE ? COLLATE utf8mb4_unicode_as_cs', ['%hce%'])->get();
注意:不要通过加
BINARY关键字的方式实现严格匹配,该写法会导致字段上的普通索引失效,数据量大时查询性能会出现明显下降。
内容的提问来源于stack exchange,提问作者devnc
相关产品推荐
相关产品推荐

