Mysql的utf8与utf8mb4字符集之间和集中排序规则之间的区别

本文深入解析了UTF-8与UTF-8MB4字符集的区别,阐述了MySQL中UTF-8MB4的引入背景及其优势,包括支持完整Unicode字符集的能力。对比了utf8mb4_bin、utf8mb4_unicode_ci与utf8mb4_general_ci的特性,讨论了排序准确性和性能之间的权衡。

utf8 与 utf8mb4

       标准的 UTF-8 字符集编码是可以用 1~4 个字节去编码21位字符,是一种变长的编码格式,这几乎包含了是世界上所有能看见的语言了。然而在MySQL里实现的utf8最长使用3个字节,节省空间但不能表达全部的UTF-8,只支持到了 Unicode 中的“基本多文种平面”(U+0000至U+FFFF,Basic Multilingual Plane,BMP),包含了控制符、拉丁文,中、日、韩等绝大多数国际字符,但并不是所有,最常见的就算现在手机端常用的表情字符 emoji和一些不常用的汉字,如 “墅” ,这些需要四个字节才能编码出来

      MySQL在 5.5.3 之后增加了 utf8mb4 字符编码,mb4即 most bytes 4,使用4个字节来表示完整的UTF-8。简单说 utf8mb4 是 utf8 的超集并完全兼容utf8,能够用四个字节存储更多的字符。

注:QQ里面的内置的表情不算,它是通过特殊映射到的一个gif图片。一般输入法自带的就是。

      当你的数据库里要求能够存入这些表情或宽字符时,可以把字段定义为 utf8mb4,同时要注意连接字符集也要设置为utf8mb4,否则在 严格模式 下会出现 Incorrect string value: /xF0/xA1/x8B/xBE/xE5/xA2… for column 'name'这样的错误,非严格模式下此后的数据会被截断。

 

utf8mb4_bin、utf8mb4_unicode_ci 与 utf8mb4_general_ci

utf8mb4_bin: 将字符串每个字符用二进制数据编译存储,区分大小写,而且可以存二进制的内容。

utf8mb4_general_ci:ci即case insensitive,不区分大小写。是一个遗留的 校对规则,不支持扩展,它仅能够在字符之间进行逐个比较,没有实现Unicode排序规则,在遇到某些特殊语言或者字符集,排序结果可能不一致。但是,在绝大多数情况下,这些特殊字符的顺序并不需要那么精确。

utf8mb4_unicode_ci:是基于标准的Unicode来排序和比较,能够在各种语言之间精确排序,Unicode排序规则为了能够处理特殊字符的情况,实现了略微复杂的排序算法。

collate规则:

utf8mb4_bin 大小写敏感

utf8mb4_general_cs 大小写敏感

*_bin: 表示的是binary case sensitive collation,也就是说是区分大小写的

*_cs: case sensitive collation,区分大小写

*_ci: case insensitive collation,不区分大小写

 Mysql默认的字符检索策略:utf8_general_ci,表示不区分大小写;utf8_general_cs表示区分大小写,utf8_bin表示二进制比较,同样也区分大小写 。(注意:在Mysql5.6.10版本中,不支持utf8_genral_cs!)

 

如何选择

字符除了需要存储,还需要排序或比较大小,涉及到与编码字符集对应的 排序字符集(collation)。ut8mb4对应的排序字符集常用的有 utf8mb4_unicode_ci、utf8mb4_general_ci。

主要从排序准确性和性能两方面看:

准确性:

utf8mb4_unicode_ci: 是基于标准的Unicode来排序和比较,能够在各种语言之间精确排序。

utf8mb4_general_ci: 没有实现Unicode排序规则,在遇到某些特殊语言或字符是,排序结果可能不是所期望的。

但是在绝大多数情况下,这种特殊字符的顺序一定要那么精确吗。比如Unicode把ß、Œ当成ss和OE来看;而general会把它们当成s、e,再如ÀÁÅåāă各自都与 A 相等。

性能:

utf8mb4_general_ci: 在比较和排序的时候更快

utf8mb4_unicode_ci: 在特殊情况下,Unicode排序规则为了能够处理特殊字符的情况,实现了略微复杂的排序算法。

但是在绝大多数情况下,不会发生此类复杂比较。general理论上比Unicode可能快些,但相比现在的CPU来说,它远远不足以成为考虑性能的因素,索引涉及、SQL设计才是。

这也从另一个角度告诉我们,不要可能产生乱码的字段作为主键或唯一索引。例如:以url来作为唯一索引,但是它记录的有可能是乱码。

总结:utf8mb4_general_ci 更快,utf8mb4_unicode_ci 更准确。推荐是 utf8mb4_unicode_ci,将来 8.0 里也极有可能使用变为默认的规则。相比选择哪一种collation,使用者更应该关心字符集与排序规则在db里需要统一。

这篇文章的原文连接:https://www.cnblogs.com/qingfengEthan/p/11326741.html

出处:http://seanlook.com/2016/10/23/mysql-utf8mb4/

MySQLutf8字符集的默认排序规则utf8_general_ci。而utf8mb4字符集的默认排序规则MySQL 8.0及以后版本中是utf8mb4_0900_ai_ci[^3]。对于早期的MySQL版本,utf8mb4的默认排序规则可能是utf8mb4_unicode_ci或者是utf8mb4_general_ci,这取决于具体的MySQL版本以及数据库的配置。 ### 排序规则说明 - **utf8_general_ci** 是utf8字符集下的一个排序规则,它提供了一种简单的排序方法,对于大多数使用情况来说已经足够。然而,它并不完全符合Unicode标准,并且在处理某些语言的特殊字符时可能不如其他更复杂的排序规则准确。 - **utf8mb4_unicode_ci** 是为utf8mb4字符集设计的排序规则,旨在MySQL 5.0及之前版本的utf8_general_ci保持兼容性。它提供了对utf8mb4字符集的支持,并且基于Unicode标准实现了更为复杂的排序算法,以处理特殊字符的情况[^1]。 - **utf8mb4_0900_ai_ci** 是MySQL 8.0引入的一个新的排序规则,基于Unicode 9.0标准(UCA 9.0.0),相比utf8mb4_unicode_ci提供了更高的准确性更好的性能,特别是在处理现代语言、表情符号特殊字符时。 ### 选择排序规则的建议 - 如果正在使用MySQL 8.0或更高版本,并且没有特定的兼容性需求,推荐使用utf8mb4_0900_ai_ci作为排序规则。这是因为utf8mb4_0900_ai_ci基于最新的Unicode标准,能够提供更好的排序准确性,尤其是在处理非拉丁字母字符时[^3]。 - 如果需要MySQL 5.x或更早版本保持兼容,或者应用程序已经依赖于utf8mb4_unicode_ci的行为,则可以继续使用utf8mb4_unicode_ci[^1]。 ### 示例代码 如果想要查看当前MySQL服务器上所有字符集及其对应的默认排序规则,可以执行以下SQL查询: ```sql SELECT CHARACTER_SET_NAME AS character_set, DEFAULT_COLLATE_NAME AS default_collation FROM INFORMATION_SCHEMA.CHARACTER_SETS; ``` 此查询将列出所有可用的字符集及其默认的排序规则,帮助确认当前MySQL实例中utf8utf8mb4字符集的默认排序规则。 ### 总结 选择合适的排序规则对于确保数据库中的数据能够正确排序比较至关重要。尽管utf8mb4_unicode_ci在特殊情况下提供了更复杂的排序算法,但在大多数情况下,选择哪一种排序规则不如确保字符集排序规则在整个数据库中的一致性重要[^2]。随着MySQL的发展,新版本推荐使用更新的排序规则utf8mb4_0900_ai_ci来获得更好的性能准确性。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值