我一直在将一些大表从latin1转换为utf8,并发现与this user相同的问题。但是我转换的表有排序规则latin1_general_ci(或latin_swedish_ci)。那么为什么MySQL在不同的字符集中对“不区分大小写”有不同的解释?因为latin1没有检查o =ö或o = oe,唯一的latin1索引会造成数千次冲突。
答案 0 :(得分:1)
有两个原因:
案例是一种语言环境。不同的语言环境可以给出不同的字符作为小写(或大写)。 IIRC土耳其语I
应该ı
(U + 0131 LATIN SMALL LETTER DOTLESS I)作为小写。参见例如Unicode Casemap FAQ。所以_swedish_
是相关的。
此外,泛型 unicode算法很复杂,并且从Unicode字符串映射到Unicode字符串。在其他字符集上使用它可能会导致问题(实现应该检查并处理转换后的案例超出原始字符集的情况)。另外,Unicode是"现代",因此MySQL用户确实不希望MySQL将字符串相等性从一个版本更改为下一个版本(例如,从Unicode到Unicode-as-first-class-charset [哪个BTW还没有这样])。
答案 1 :(得分:0)
具有语言名称或国家/地区代码的排序规则适合该语言。例如,瑞典语在Å
(“超越斑马”之后)对Z
(A-ring)进行排序?大多数其他语言将其排序与A
相同。
请注意,有几种不同的latin1排序规则,以及大量的utf8排序规则。
我使用utf8_general_mysql500_ci
here捕获了ß
的历史记录和问题。
MySQL的...general...
排序规则一次只查看一个字节,因此将'oe'或'ss'或'll'视为2个字母。 “一般”更快,但很少有用。
...bin
只检查字节。无折叠;没有重音剥离。
MySQL几乎在所有排序规则(...ci
)中将案例折叠和重点剥离联系在一起。只有少数...cs
(“区分大小写”)。
在各种utf8排序规则中查看相同或不同的内容:http://mysql.rjweb.org/utf8_collations.html
对于utf8mb4(MySQL 8.0):http://mysql.rjweb.org/utf8mb4_collations.html