最新下载
热门教程
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
如何修复MySQL因字符序不匹配导致的Illegal mix of collations?
时间:2026-06-19 08:56:03 编辑:袖梨 来源:一聚教程网
必须先定位再修改collation,否则易改错表、漏字段或继承旧默认值;执行三条SQL查库、表、列的排序规则,重点检查是否混用不同后缀的utf8mb4 collation。
查清 collation 混用的具体位置
不先定位就改,大概率改错表、漏字段,甚至让新字段继承旧库默认值。执行这三条语句快速摸清现状:
SELECT DEFAULT_COLLATION_NAME FROM information_schema.SCHEMATA WHERE SCHEMA_NAME = 'your_db_name';SELECT TABLE_NAME, TABLE_COLLATION FROM information_schema.TABLES WHERE TABLE_SCHEMA = 'your_db_name';SELECT COLUMN_NAME, COLLATION_NAME FROM information_schema.COLUMNS WHERE TABLE_SCHEMA = 'your_db_name' AND TABLE_NAME = 'your_table' AND COLLATION_NAME IS NOT NULL;
重点看结果里是否混着 utf8mb4_general_ci、utf8mb4_unicode_ci、utf8mb4_0900_as_cs 这类不同后缀的规则——只要参与 =、IN、JOIN 或 UNION 的列 collation 不一致,1267 错误随时触发。
ALTER TABLE CONVERT TO 要慎用
CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci 看似一步到位,但它会重写整张表,大表执行期间锁表、耗 I/O、可能拖垮线上服务。
更稳妥的做法是分层对齐:
- 先改库级默认:
ALTER DATABASE your_db_name CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci; - 再批量改表(仅改表定义,不重写数据):
ALTER TABLE your_table ROW_FORMAT=DYNAMIC;+ALTER TABLE your_table CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;(小表可直接用,大表建议拆成MODIFY COLUMN逐字段改) - 只改问题字段:
ALTER TABLE your_table MODIFY COLUMN col_name VARCHAR(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
别选 utf8mb4_general_ci——MySQL 8.0+ 已弃用,utf8mb4_unicode_ci 兼容性更稳,utf8mb4_0900_as_cs 区分大小写但需确认业务是否依赖该行为。
触发器和视图里必须显式 COLLATE
即使表和库全统一了,触发器仍可能报错。因为触发器执行时用的是会话级 @@collation_connection,不是字段本身的 collation。
在触发器中所有字符串操作都得加 COLLATE:
IF NEW.name COLLATE utf8mb4_unicode_ci = 'admin' COLLATE utf8mb4_unicode_ci THEN-
SET v_name = NEW.name COLLATE utf8mb4_unicode_ci;(变量声明也要带:DECLARE v_name VARCHAR(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;) - 函数参数不能漏:
UPPER(NEW.name COLLATE utf8mb4_unicode_ci)
视图创建失败也常因 SELECT 中混了常量和字段:字符串字面量(如 'active')默认继承连接层 collation,必须写成 CONVERT('active' USING 'utf8mb4') COLLATE utf8mb4_unicode_ci 才能通过 CREATE VIEW 校验。
临时绕过别乱用 CONVERT
CONVERT(col USING 'utf8mb4') 只改字符集,不带 collation;返回类型是 CHAR,会导致索引失效、类型隐式转换、后续比较再次出错。
真正可控的临时方案是 COLLATE:
WHERE t1.name COLLATE utf8mb4_unicode_ci = t2.name COLLATE utf8mb4_unicode_ciSELECT ... FROM t1 JOIN t2 ON t1.id = t2.ref_id AND t1.code COLLATE utf8mb4_unicode_ci = t2.code COLLATE utf8mb4_unicode_ci
如果非得用 CONVERT,必须配 COLLATE:例如 CONVERT(col USING 'utf8mb4') COLLATE utf8mb4_unicode_ci,且注意长度截断风险——CONVERT(col AS CHAR(255) CHARACTER SET utf8mb4) COLLATE utf8mb4_unicode_ci 中的 255 必须 ≥ 字段实际最大长度。
最容易被忽略的是:连接层 collation 和客户端字符集不一致时,连 SET NAMES utf8mb4 都不一定生效,得在连接串里加 ?charset=utf8mb4 或执行 SET collation_connection = 'utf8mb4_unicode_ci'; 才能兜住源头。
相关文章
- 明末渊虚之羽防具有哪些排名 07-02
- 如何获取和平精英皮肤照片 07-02
- 空洞骑士丝之歌如何获取制造金属 07-02
- 鱼骨头螃蟹阵容如何搭配 07-02
- 战魂旅人玩法是什么 07-02
- 无限暖暖祝你幸福发饰如何获取 07-02