德语客户列表在页面上 Ä 开头排在 A 后面,导出后跑到 Z 之后,同一份数据两个顺序,运营核对时漏了 4 个客户。碰到这种情况,我一般先确认改动有没有真的生效。
原因不复杂,页面用 Java Collator 按德语规则排序,SQL 用 utf8mb4_general_ci,两者对变音字母的权重定义不同。导出走的是数据库排序,页面走的是内存排序。两种规则混用,顺序自然对不上。
碰到「语言排序规则」这类问题,我习惯先把当前配置原样备份一份,改坏了立刻换回来,不用现场推。别只看报错的最后一行,往上看几行,真正的起因通常在上面。
SELECT name FROM customer ORDER BY name COLLATE utf8mb4_de_pb_0900_ai_ci;
Collator.getInstance(Locale.GERMAN).compare("Ä", "Z");
同类问题如果隔一段时间又出现,多半是某个定时任务或重启流程把改动冲掉了。
具体做法是,排序统一在一层做 要么全在 SQL 要么全在应用;数据库侧用与语言匹配的 collation 或按拼音列排序;应用侧显式指定 Locale.GERMAN 的 Collator;拿 Ä、A、Z 三个值在两边各排一次对比。
最后用这个标准收尾,页面和导出的客户顺序一致,Ä 开头都紧跟在 A 之后。
