一尘不染

utf8_general_ci和utf8_unicode_ci有什么区别?

mysql

utf8_general_ci和之间utf8_unicode_ci,在效果方面是否存在差异?


阅读 354

收藏
2020-05-17

共1个答案

一尘不染

这两个归类均适用于UTF-8字符编码。区别在于文本的排序和比较方式。

注意:在MySQL中,您必须使用utf8mb4而不是utf8。令人困惑的是,utf8是早期MySQL版本中有缺陷的UTF-8实现,仅用于向后兼容。固定版本的名称为utf8mb4

注意:较新版本的MySQL已更新了Unicode排序规则,可以在名称下使用,例如 utf8mb4_0900_ai_ci 基于Unicode
9.0的等效规则-且没有等效
_general 变体。 现在阅读此书的人们可能应该使用这些较新的排序规则之一,而不是 _unicode
or _general如果您可以使用一种新的排序规则来代替,那么下面编写的大部分内容都将不再有意义。

关键差异

  • utf8mb4_unicode_ci 基于用于通用排序和比较的官方Unicode规则,该规则可以在多种语言中进行准确排序。

  • utf8mb4_general_ci是一组简化的排序规则,旨在尽力而为,同时采用许多旨在提高速度的捷径。它不遵循Unicode规则,在某些情况下(例如,使用特定语言或字符时)会导致不希望的排序或比较。

在现代服务器上,这种性能提升几乎可以忽略不计。它是在服务器仅具有当今计算机CPU性能的一小部分的时候设计的。

utf8mb4_unicode_ci 超过的好处utf8mb4_general_ci

utf8mb4_unicode_ci使用Unicode规则进行排序和比较,它使用相当复杂的算法来对多种语言和使用多种特殊字符进行正确排序。这些规则需要考虑到特定于语言的约定。并非每个人都按照我们称为“字母顺序”的顺序对字符进行排序。

就拉丁语(即“欧洲”)语言而言,Unicode排序与utf8mb4_general_ciMySQL中的简化排序之间并没有太大差异,但仍然存在一些差异:

  • 例如,Unicode归类对使用那些字符的人通常希望将“ß”(如“ ss”)和“Œ”(如“ OE”)进行utf8mb4_general_ci排序,而将它们排序为单个字符(大概分别像“ s”和“ e” 。

  • 一些Unicode字符被定义为可忽略,这意味着它们不应该计入排序顺序,而比较应该继续到下一个字符。 utf8mb4_unicode_ci正确处理这些。

在非拉丁语言(例如亚洲语言或具有不同字母的语言)中,Unicode排序和简化排序之间可能会有 更多
差异utf8mb4_general_ci。的适用性utf8mb4_general_ci将在很大程度上取决于所使用的语言。对于某些语言,这将是远远不够的。

你应该用什么?

几乎肯定没有理由再使用utf8mb4_general_ci了,因为我们已经落后了CPU速度足够低而性能差异很重要的地步。您的数据库几乎肯定会受到其他瓶颈的限制。

过去,有人建议使用,utf8mb4_general_ci除非准确的分类变得足够重要以证明性能成本合理。今天,这种性能成本几乎消失了,开发人员正在更加认真地对待国际化。

有一种观点认为,如果速度对您而言比准确性更重要,那么您可能根本不做任何排序。如果不需要精确的算法,则可以使算法更快。因此,这utf8mb4_general_ci是一种折衷方案,出于速度原因可能不需要,而且出于准确性原因也可能不合适。

我要补充的另一件事是,即使您知道您的应用程序仅支持英语,它仍可能需要处理人的名字,该名字通常可以包含其他语言中使用的字符,在这些语言中正确排序同样重要。对所有内容使用Unicode规则有助于让您放心,非常聪明的Unicode人员为使排序正常工作而进行了非常努力的工作。

零件是什么意思

首先,ci不区分大小写的
排序和比较。这意味着它适用于文本数据,并且大小写并不重要。其他排序规则是cs(区分大小写的)区分大小写的文本数据bin,对于需要匹配的编码,一点一点的排序,这适用于真正编码二进制数据的字段(例如,
Base64)。区分大小写的排序会导致一些奇怪的结果,并且区分大小写的比较可能导致重复值仅在字母大小写上有所不同,因此区分大小写的排序规则对文本数据不受欢迎-
如果大小写对您来说很重要,则标点符号会被忽略等等也可能很重要,二进制排序可能更合适。

接下来,unicodegeneral指的是特定的排序和比较规则-
特别是规范化或比较文本的方式。有对utf8mb4字符编码许多不同的规则集,以unicodegeneral为两块尝试工作以及在所有可能的语言,而不是一个具体的一个。这两组规则之间的差异是此答案的主题。请注意,它unicode使用Unicode
4.0中的规则。MySQL的最新版本unicode_520使用Unicode 5.2中的规则添加规则集,并0900使用Unicode
9.0中的规则添加(删除“ unicode_”部分)。

最后,utf8mb4当然是内部使用的字符编码。在这个答案中,我仅谈论基于Unicode的编码。

2020-05-17