必须先定位再修改collation,否则易改错表、漏字段或继承旧默认值;执行三条SQL查库、表、列的排序规则,重点检查是否混用不同后缀的utf8mb4 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 错误随时触发。
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 区分大小写但需确认业务是否依赖该行为。
即使表和库全统一了,触发器仍可能报错。因为触发器执行时用的是会话级 @@collation_connection,不是字段本身的 collation。
在触发器中所有字符串操作都得加 COLLATE:
IF NEW.name COLLATE utf8mb4_unicode_ci = 'admin' COLLATE utf8mb4_unicode_ci THENSET 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(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'; 才能兜住源头。