Mysql

关注公众号 jb51net

关闭
首页 > 数据库 > Mysql > MySQL 1267错误

MySQL 1267错误的根本原因分析:排序规则冲突的原因与解决方案

作者:mister_guo

本文告诉你Illegal mix of collations的根本原因,即两个字符串使用了不同排序规则,即使字符集相同也会报错,你将学会从报错信息定位冲突规则,并通过显式使用COLLATE或统一字段排序规则来彻底解决问题,避免在关联查询时再次遇到

MySQL-1267错误(Illegal mix of collations)的根本原因是:‌参与比较的两个字符串对象使用了不同的排序规则(Collation)‌,MySQL无法判断该按哪套规则进行比较,所以直接报错中断执行。字符集(Charset)相同不代表排序规则相同,这是最常见的误区。

‌快速定位方法‌:从报错信息中读取冲突的两个排序规则名称(如 utf8mb4_general_ci 和 utf8mb4_0900_ai_ci),然后用 SHOW CREATE TABLE 和查询 information_schema.COLUMNS 找到具体是哪些字段、哪些表使用了这些规则,再选择对应的解决方案。

一、问题背景

        执行关联查询时,有时会遇到下面的错误:

SELECT s.* 
FROM sg_corporatesign s
JOIN pj_billsignrecord d ON d.signFullName = s.name AND d.signStatus = 2;

1267 - Illegal mix of collations (utf8mb4_0900_ai_ci,IMPLICIT) and (utf8mb4_unicode_ci,IMPLICIT) for operation '='

        错误的意思是:参与等值比较的两个字符串使用了不同的排序规则,MySQL 无法为这次比较自动确定采用哪一个规则。

二、问题分析

1、都用了 utf8mb4,为什么还会报错?

字符集和排序规则是两个不同的概念:

概念解决的问题示例
字符集(Character Set)字符如何编码、可以表示哪些字符utf8mb4
排序规则(Collation)字符串如何比较大小、判断相等和排序utf8mb4_unicode_ci

两个字段都能存中文,并不意味着它们采用相同的比较规则。

本次错误涉及的规则中,signFullName使用的是utf8mb4_0900_ai_ci排序规则,而utf8mb4_0900_ai_ci基于 Unicode 9.0 的排序算法,ai 表示不区分重音,ci 表示不区分大小写;name使用的是utf8mb4_unicode_ci排序规则,utf8mb4_unicode_ci是较早的 Unicode 排序规则,也不区分大小写。它们不能简单地视为同一个规则的两个名字。一旦两个关联字段的排序规则不一致的话,就可能产生本文出现的错误。

2、问题通常是怎么出现的?

常见原因是表结构经过多次演变,相关字段的定义逐渐不一致:

3、解决方案

(1)、在查询中显式指定 COLLATE

当暂时不能修改表结构时,可以明确指定比较采用的规则:

SELECT s.* 
FROM sg_corporatesign s
JOIN pj_billsignrecord d ON d.signFullName COLLATE utf8mb4_unicode_ci = s.name COLLATE utf8mb4_unicode_ci AND d.signStatus = 2;

COLLATE 在 MySQL 中表示指定字符串的比较和排序规则,也可以理解为使用显式统一的规则来进行比较。当然,也不会修改字段本身的定义或保存的数据。

(2)、统一相关字段的排序规则

如果两个字段长期用于关联,通常应该在结构层面统一定义。假设已经确定sg_corporatesign表的name字段,与pj_billsignrecord表的signFullName字段的排序规则应该设置为相同。

ALTER TABLE pj_billsignrecord
MODIFY COLUMN signFullName VARCHAR(32) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL;

三、小结

    总上所述,COLLATE 用于指定字符串的比较和排序规则,决定比较时是否区分大小写、重音等。字符集相同的字段,也可能因为排序规则不同,在关联或等值比较时触发 Illegal mix of collations 错误。临时处理可以在 SQL 中通过 COLLATE 明确比较规则;长期解决则应根据业务需求,统一相关字段的排序规则,并验证查询结果、唯一约束和索引使用情况。

到此这篇关于MySQL 1267错误的根本原因分析:排序规则冲突的原因与解决方案的文章就介绍到这了,更多相关MySQL 1267错误内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

您可能感兴趣的文章:
阅读全文