mysql - utf8_general_ci和utf8_unicode_ci有什么区别?

标签 mysql unicode utf-8 collation character-set

utf8_general_ciutf8_unicode_ci之间,在性能方面有什么区别吗?

最佳答案

对于仍在2020年或更晚时间提出此问题的人们,有一些较新的选择可能比这两者都更好。例如,utf8mb4_0900_ai_ci
所有这些归类均适用于UTF-8字符编码。区别在于文本的排序和比较方式。_unicode_ci_general_ci是用于根据我们期望的方式对文本进行排序和比较的两组不同规则。较新版本的MySQL也引入了新的规则集,例如用于基于Unicode 9.0的等效规则的_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规则进行排序和比较,它使用相当复杂的算法来对多种语言和使用多种特殊字符进行正确排序。这些规则需要考虑到特定于语言的约定。并非每个人都按照我们称为“字母顺序”的顺序对字符进行排序。
    就拉丁(即“欧洲”)语言而言,Unicode排序与MySQL中简化的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)。区分大小写的排序会导致一些奇怪的结果,并且区分大小写的比较可能导致重复值仅在字母大小写上有所不同,因此区分大小写的排序规则对文本数据不受欢迎-如果大小写对您而言很重要,则否则会出现标点等等也可能很重要,而二进制排序规则可能更合适。
    接下来,unicodegeneral指的是特定的排序和比较规则-尤其是规范化或比较文本的方式。 utf8mb4字符编码有许多不同的规则集,unicodegeneral是两种试图在所有可能的语言中都能正常工作的规则,而不是一种特定的语言。这两组规则之间的差异是此答案的主题。请注意,unicode使用Unicode 4.0中的规则。 MySQL的最新版本使用Unicode 5.2中的规则添加规则集unicode_520,并使用Unicode 9.0中的规则添加0900(删除“unicode_”部分)。
    最后,utf8mb4当然是内部使用的字符编码。在这个答案中,我仅谈论基于Unicode的编码。

    关于mysql - utf8_general_ci和utf8_unicode_ci有什么区别?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1987572/

    相关文章:

    jsf - PrimeFaces 3.x 中的 UTF-8

    PHP PCRE 模式

    mysql - 在配置单元中创建数据库失败

    mysql - 使用 spring、hibernate 和 mysql 设置 pom.xml

    mysql - php无法连接到docker-compose中的mysql

    Python:如何将 Windows 1251 转换为 Unicode?

    Unicode 字符 xn--ls8h

    python - Pandas 将数据帧转换为 Utf-8

    php - 从 SQL 数据库中选择数据返回 "1"

    C++ 项目类型 : unicode vs multi-byte; pros and cons