邀请码表唯一索引,插入 ABC 后插入 abc 报 1062 Duplicate entry 'abc',业务认为这是两个不同的码。第一次遇到会往复杂处想,其实漏掉的多是个小前提。
SHOW FULL COLUMNS FROM invites LIKE 'code';
ALTER TABLE invites MODIFY code VARCHAR(32) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin;
INSERT INTO invites (code) VALUES ('abc');
_ci 结尾的 collation 比较时忽略大小写,唯一索引按比较结果判重,两个值被视为相同。_bin 或 _as_cs 才会区分。这一点先确认清楚,后面就不用反复试。
「排序规则大小写」这个问题文档写得含糊,实际行为以当前版本为准,别照旧版本的结论套。临时改动用注释写上日期和原因,过两周自己都记不清为什么这么写。
动手前把原文件复制一份带时间戳,出问题立刻换回去,比现场分析快得多。一次只改一处,改完立刻验证,几个改动叠在一起,出问题就说不清是谁导致的。
先做最小复现,能稳定跑出来的问题,排查成本会低一个数量级。
具体做法是,需要区分大小写就把列改成 utf8mb4_bin;或改用 _as_cs 的排序规则;已经建好的索引要重建 改列不会自动换 collation;确认查询条件也按同一规则比较。
改完照着核一遍,ABC 和 abc 能同时存在 按 code 精确查询只返回对应那一条。
