德语用户名 straße 提交时转大写存库,注册接口报长度超限,上限写的 20,存进去变成 STRASSE,原值和大写值字节数不同,登录时原样输入匹配不上。乍看像缓存或者权限的锅,追下去往往不是。
'straße'.toUpperCase() 'İ'.toLowerCase() 'ß'.toUpperCase().length
追下去是这么回事:大写映射不是一对一,ß 的大写形式是两个字符 SS,土耳其语 i 还会变成 İ。按大写结果做唯一键或长度校验,和用户输入的原值就对不上。
「toUpperCase 长度变化」这个问题文档写得含糊,实际行为以当前版本为准,别照旧版本的结论套。一次只改一处,改完立刻验证,几个改动叠在一起,出问题就说不清是谁导致的。
先做最小复现,能稳定跑出来的问题,排查成本会低一个数量级。
具体做法是,存原值 另存一列归一化后的值用于比较;归一化用 toLowerCase 加 locale 参数 不要用默认 locale;长度校验按原值算 不要按转换后的值;唯一索引建在归一化列上 并确认 collation 行为。
验收就看一点,原值能原样登录 唯一键比较不受大小写变形影响。
