在utf8\u general\u ci
和utf8\u unicode\u ci
之间,性能是否有任何差异
对于那些在2020年或更晚的时候仍然面临这个问题的人来说,有一些新的选择可能比这两者都好。例如,utf8mb4\u 0900\u ai\u ci
所有这些排序规则都用于UTF-8字符编码。区别在于文本的排序和比较方式
\u unicode\u ci
和\u general\u ci
是两套不同的规则,用于根据我们期望的方式对文本进行排序和比较。MySQL的较新版本也引入了新的规则集,例如基于Unicode 9.0的等效规则的\u 0900\u ai\u ci
,并且没有等效的\u general\u ci
变体。现在阅读本文的人可能应该使用这些较新的排序规则之一,而不是\unicode\u ci
或\u general\u ci
。下面对这些旧排序规则的描述仅供参考
MySQL目前正在从一个旧的、有缺陷的UTF-8实现过渡。现在,您需要对字符编码部分使用utf8mb4
而不是utf8
,以确保获得固定版本。有缺陷的版本仍保留向后兼容性,尽管它已被弃用。
关键差异
-
utf8mb4\u unicode\u ci
基于通用排序和比较的官方unicode规则,可在多种语言中准确排序 -
utf8mb4\u general\u ci
是一组简化的排序规则,目的是在尽可能好地执行排序规则的同时,采取许多旨在提高速度的捷径。它不遵循Unicode规则,在某些情况下会导致不希望的排序或比较,例如在使用特定语言或字符时在现代服务器上,这种性能提升几乎可以忽略不计。它是在服务器的CPU性能只有当今计算机的一小部分的时候设计的
与utf8mb4\u unicode\u ci相比,
utf8mb4\u unicode\u ci的优点
utf8mb4_unicode_ci
,它使用unicode规则进行排序和比较,使用相当复杂的算法在各种语言中以及在使用各种特殊字符时进行正确排序。这些规则需要考虑到特定语言的惯例;并不是每个人都按照我们所说的“字母顺序”对他们的角色进行排序
就拉丁语(即“欧洲”语言而言,Unicode排序与MySQL中的简化utf8mb4_general\u ci
排序没有太大区别,但仍有一些区别:
-
例如,Unicode排序规则对“排序”;ß;例如;ss";,及;Œ;例如;OE“;正如使用这些字符的人通常希望的那样,而
utf8mb4“u general”ci
将它们作为单个字符进行排序(可能分别类似于“s”和“e”) -
某些Unicode字符被定义为可忽略的,这意味着它们不应按排序顺序计数,而应将比较移到下一个字符
utf8mb4\u unicode\u ci
正确处理这些问题
在非拉丁语言中,例如亚洲语言或字母表不同的语言中,Unicode排序和简化的utf8mb4_general_ci排序之间可能存在许多差异。utf8mb4\u general\u ci
的适用性在很大程度上取决于所使用的语言。对于某些语言来说,这是相当不够的
您应该使用什么?
几乎可以肯定的是,没有理由再使用utf8mb4\u general\u ci
,因为我们已经忽略了CPU速度低到性能差异非常重要的一点。您的数据库几乎肯定会受到其他瓶颈的限制
过去,有些人建议使用utf8mb4\u general\u ci
,除非准确排序非常重要,足以证明性能成本是合理的。如今,这种性能成本几乎消失了,开发人员正在更加认真地对待国际化
有一种观点认为,如果速度对你来说比准确性更重要,你最好根本不做任何排序。如果您不需要精确的算法,那么让算法更快就很简单了。因此,utf8mb4_general_ci
是一种折衷方案,可能出于速度原因不需要,也可能出于精度原因不适合
我要补充的另一件事是,即使您知道您的应用程序只支持英语,它可能仍然需要处理人名,人名通常包含在其他语言中使用的字符,正确排序同样重要。使用Unicode规则有助于消除人们的疑虑,因为非常聪明的Unicode人员非常努力地使排序工作正常
零件的含义
首先,ci
用于不区分大小写的排序和比较。这意味着它适用于文本数据,大小写并不重要。其他类型的排序规则是cs
(区分大小写),用于区分大小写的文本数据,以及bin
,用于编码需要匹配的位置,逐位排序,适用于真正编码的二进制数据字段(例如,包括Base64)。区分大小写的排序会导致一些奇怪的结果,区分大小写的比较可能会导致重复的值,这些值仅在字母大小写上有所不同,因此区分大小写的排序规则不适合于文本数据-如果大小写对您来说很重要,那么其他可忽略的标点符号等可能也很重要,二进制排序可能更合适
接下来,unicode
或general
指的是特定的排序和比较规则,特别是文本规范化或比较的方式。utf8mb4字符编码有许多不同的规则集,unicode
和general
是两种试图在所有可能的语言中都能很好地工作的规则,而不是一种特定的语言。这两套规则之间的差异是这个答案的主题。请注意,unicode
使用unicode 4.0中的规则。MySQL的最新版本使用unicode 5.2中的规则添加规则集unicode_520
,并使用unicode 9.0中的规则添加0900
(删除“unicode”部分)
最后,utf8mb4
当然是内部使用的字符编码。在这个答案中,我只讨论基于Unicode的编码