如何在MySQL中全局忽略排序规则不匹配问题?
问题描述
在应用前端搜索UTF-8字符时,遭遇排序规则非法混合问题:
- 多列搜索场景中,多数列采用
utf8mb4编码,仅一列使用ascii编码 - 搜索纯ASCII字符时查询正常:
SELECT * FROM some_table WHERE utf8_column LIKE '%search%' OR ascii_column LIKE '%search%' - 搜索非ASCII字符(如
ツ)时触发错误:1267 - Illegal mix of collations (ascii_general_ci,IMPLICIT) and (utf8mb4_0900_ai_ci,COERCIBLE) for operation 'like'
约束条件:
- 不希望修改应用层代码(需大量改动且易遗漏)
- 无法将ascii列转为UTF-8(关联大表时ascii编码查询速度比UTF-8快25%)
- 需求:MySQL端全局处理,排序规则不匹配时对应条件返回
false而非报错
解决方案
方案1:开启NO_COLLATION_ERROR SQL模式(MySQL 8.0.17+)
MySQL 8.0.17及以上版本支持NO_COLLATION_ERROR模式,开启后排序规则不匹配的比较操作不会抛出错误,而是返回NULL(在OR条件中等同于false)。
临时生效(会话级)
SET SESSION sql_mode = CONCAT(@@sql_mode, ',NO_COLLATION_ERROR');
永久生效(全局级)
修改MySQL配置文件my.cnf(Windows为my.ini):
[mysqld] sql_mode = NO_COLLATION_ERROR,你的现有SQL模式
重启MySQL服务后生效。
开启后,非ASCII字符查询中ascii_column LIKE '%ツ%'会返回false,查询仅执行utf8_column的匹配逻辑,无报错。
方案2:全局调整连接排序规则(兼容旧版本)
若使用MySQL 8.0.17以下版本,可全局设置collation_connection为ascii_general_ci,让客户端发送的字符串统一转换为该排序规则,非ASCII字符在ascii列的LIKE查询中自然无法匹配(返回false),避免排序规则冲突。
临时生效
SET GLOBAL collation_connection = 'ascii_general_ci'; SET SESSION collation_connection = 'ascii_general_ci';
永久生效
修改配置文件:
[mysqld] collation_connection = ascii_general_ci
重启服务后生效。
注意:该设置会影响所有客户端连接的字符串处理逻辑,需确认其他业务场景兼容性。
验证效果
执行非ASCII字符查询:
SELECT * FROM some_table WHERE utf8_column LIKE '%ツ%' OR ascii_column LIKE '%ツ%';
此时无1267错误,结果仅包含utf8_column匹配的行,符合需求。
内容的提问来源于stack exchange,提问作者hakai
相关产品推荐
相关产品推荐

