Mysql 为什么latin1和utf8不区分大小写?

Mysql 为什么latin1和utf8不区分大小写?,mysql,utf-8,collation,iso-8859-1,Mysql,Utf 8,Collation,Iso 8859 1,我一直在将一些大型表从latin1转换为utf8,并发现与相同的问题。但我所转换的表有拉丁字母1_general_ci(或拉丁字母u瑞典语_ci)的排序规则。那么为什么MySQL在不同的字符集中对“不区分大小写”有不同的解释呢?因为latin1不检查o=ö或o=oe,所以一个独特的latin1索引会造成数千次冲突。原因有两个: 这个案子是现场的事。不同的地区可能会提供不同的字符作为小写(或大写)。IIRC土耳其语I应使用ı(U+0131拉丁文小写字母DOTLESS I)作为小写。见例。因此,\u

我一直在将一些大型表从latin1转换为utf8,并发现与相同的问题。但我所转换的表有拉丁字母1_general_ci(或拉丁字母u瑞典语_ci)的排序规则。那么为什么MySQL在不同的字符集中对“不区分大小写”有不同的解释呢?因为latin1不检查o=ö或o=oe,所以一个独特的latin1索引会造成数千次冲突。

原因有两个:

这个案子是现场的事。不同的地区可能会提供不同的字符作为小写(或大写)。IIRC土耳其语
I
应使用
ı
(U+0131拉丁文小写字母DOTLESS I)作为小写。见例。因此,
\u瑞典语
是相关的


此外,通用unicode算法比较复杂,并且可以从unicode字符串映射到unicode字符串。在其他字符集上使用它可能会导致问题(实现应该检查并以不同方式处理转换后的case在原始字符集之外的情况)。此外,Unicode是“现代的”,因此MySQL用户不希望MySQL将字符串相等性从一个版本更改为下一个版本(例如,将Unicode之前的字符集更改为Unicode作为第一类字符集[顺便说一句,现在还不是这样]。

带有语言名称或国家代码的排序规则是针对该语言定制的。例如,瑞典语在
Z
之后排序
Å
(A环)(“在斑马之外”?)大多数其他语言将排序与
A
相同

请注意,有几个不同的latin1排序规则和许多utf8排序规则

我捕获了
utf8_general_mysql500_ci
的历史以及
ß
的问题

MySQL的
…general…
排序规则一次只查看一个字节,因此将“oe”或“ss”或“ll”视为两个字母“通用”更快,但很少有用

…bin
只检查字节。无箱子折叠;没有口音剥离

MySQL在几乎所有的排序规则(
…ci
)中都将大小写折叠和重音清除联系在一起。只有少量的
…cs
(“区分大小写”)

要查看各种utf8排序规则中的相等项或不相等项:

对于utf8mb4(MySQL 8.0):

我同意存在区域设置问题,并且我很惊讶使用例如utf8\u german2.ci没有帮助(尽管有问题的表偏离了此范围)。但你问题的第二部分似乎说latin1可以追溯到任何人想到它之前,他们不想改变它,因为它可能会破坏许多现有的数据库。还有比这更好的理由吗?我必须准确地测试哪些字符的解释不同。Unicode试图有一个更合理的算法,可以在所有语言上通用。Latin1更倾向于一些西欧的排序规则。我没有做过详尽的测试,但总体上是用Latin1'a'!='á,“e”!='è,“我”!='î,“o”!='而在utf-8中,这些都是相等的。我错了,来自mysql:“xxx_general_mysql500_ci排序保留了原始xxx_general_ci排序在5.1.24之前的顺序,并允许升级mysql 5.1.24之前创建的表”,所以稳定性不是问题。我也错了,
uf8\u generic\u ci
使用unicode算法。(
uf8\u unicode\u ci
这样做)。所以这是纯粹的mysql实现细节。请参阅以获得一些描述,但没有关于latin1_generic()的原因。