mysql建库时选择的utf8_general_ci和utf8_unicode_ci有什么区别?

摘自stackoverflow上的一个回答:

对于那些在 2020 年或之后仍在阅读这个问题的人来说,有一些新的选项可能比这两个都更好。例如,utf8_unicode_520_ci

所有这些排序规则都适用于 UTF-8 字符编码。它们之间的区别在于文本的排序和比较方式。

_unicode_ci_general_ci 是两种不同的排序和比较文本的规则集,根据我们的预期方式进行排序和比较。 MySQL 的新版本也引入了新的规则集,比如基于 Unicode 5.2 的 _unicode_520_ci,或者基于 Unicode 9.0 的 MySQL 8.x 特有的 _0900_ai_ci(并且没有相应的 _general_ci 变体)。现在阅读这篇文章的人应该使用这些更新的排序规则之一,而不是使用 _unicode_ci_general_ci。下面提供的关于那些较旧排序规则的描述仅供参考。

MySQL 目前正在过渡到一个较旧的、有缺陷的 UTF-8 实现。目前,为了确保使用了修复的版本,您需要使用 utf8mb4 而不是 utf8 作为字符编码部分。虽然有缺陷的版本仍然保留了向后兼容性,但它正在被弃用。

主要区别

utf8mb4_unicode_ci 基于官方的 Unicode 规则进行普遍的排序和比较,可以准确地对多种语言进行排序。

utf8mb4_general_ci 是一组简化的排序规则,旨在在尽可能提高速度的同时尽量做得更好。它不遵循 Unicode 规则,在某些情况下会导致不良的排序或比较,例如在使用特定语言或字符时。

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

utf8mb4_unicode_ci 相对于 utf8mb4_general_ci 的优势

utf8mb4_unicode_ci 使用 Unicode 规则进行排序和比较,采用了一种相当复杂的算法,可以在广泛的语言和使用广泛的特殊字符时进行正确的排序。这些规则需要考虑特定语言的约定;并不是每个人都会按照我们所谓的“字母顺序”来排序他们的字符。

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

例如,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 的二进制数据)。区分大小写的排序会导致一些奇怪的结果,而区分大小写的比较可能导致仅在字母大小写不同时出现重复值,因此区分大小写的排序规则在文本数据中已经不再受欢迎 – 如果大小写对您很重要,那么否则可以忽略的标点符号等也可能很重要,而二进制排序规则可能更合适。

其次,unicode 或 general 指的是具体的排序和比较规则 – 特别是文本规范化或比较方式。对于 utf8mb4 字符编码,有许多不同的规则集,其中 unicode 和 general 是其中两个旨在在所有可能的语言中工作良好而不是一个特定语言的规则。这两个规则集之间的区别是本答案的主题。请注意,unicode 使用 Unicode 4.0 的规则。MySQL 和 MariaDB 的最新版本添加了 ruleset unicode_520,使用 Unicode 5.2 的规则,MySQL 8.x 添加了 0900(去掉了“unicode_”部分),使用 Unicode 9.0 的规则。

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

mysql建库时选择的utf8_general_ci和utf8_unicode_ci有什么区别?

原文链接:https://beltxman.com/4057.html,若无特殊说明本站内容为 行星带 原创,未经同意禁止转载。

发表评论

您的电子邮箱地址不会被公开。

Scroll to top