我正在尝试找出应该对各种类型的数据使用什么排序规则。我将存储的内容 100% 是用户提交的。
我的理解是我应该使用 UTF-8 General CI(不区分大小写)而不是 UTF-8 Binary。但是,我找不到 UTF-8 General CI 和 UTF-8 Unicode CI 之间的明确区别。
一般来说,utf8_general_ci比utf8_unicode_ci更快,但不太正确。
区别如下:
对于任何 Unicode 字符集,使用 _general_ci 排序规则执行的操作比使用 _unicode_ci 排序规则执行的操作更快。例如,与 utf8_unicode_ci 的比较相比,utf8_general_ci 排序规则的比较速度更快,但正确性稍差。原因是utf8_unicode_ci支持扩展等映射;也就是说,当一个字符与其他字符的组合进行比较时等于。例如,在德语和其他一些语言中,“ß”等于“ss”。 utf8_unicode_ci 还支持缩写和可忽略字符。 utf8_general_ci 是一种遗留排序规则,不支持扩展、收缩或可忽略字符。它只能在字符之间进行一对一的比较。
引自: http://dev.mysql.com/doc/refman/5.0/en/charset-unicode-sets.html
更详细的解释,请阅读MySQL论坛的以下帖子: http://forums.mysql.com/read.php?103,187048,188748
对于utf8_bin: utf8_general_ci 和 utf8_unicode_ci 都执行不区分大小写的比较。相比之下,utf8_bin 区分大小写(以及其他差异),因为它比较字符的二进制值。
您还应该意识到这样一个事实,即使用 utf8_general_ci 当使用 varchar 字段作为唯一或主索引时插入 2 个值(如“a”和“á”)会产生重复键错误。
utf8_bin
盲目比较位。没有大小写折叠,没有重音剥离。utf8_general_ci
将一个代码点与一个代码点进行比较。它会进行大小写折叠 和 重音剥离,但不进行 2 个字符的比较;例如:在此排序规则中,ij
不等于 ij
。utf8_*_ci
是一组特定于语言的规则,但其他方面与 unicode_ci
类似。一些特殊情况:Ç
、Č
、ch
、ll
utf8_unicode_ci
遵循旧的 Unicode 标准进行比较。 ij
=ij
,但是ae
!=æ
utf8_unicode_520_ci
遵循较新的 Unicode 标准。 ae
=æ
请参阅排序规则表,了解有关各种 utf8 排序规则中的内容等于什么的详细信息。
utf8
,由 MySQL 定义,仅限于 1 到 3 字节的 utf8 代码。这就排除了表情符号和一些中文。因此,如果您想超越欧洲,您真的应该切换到utf8mb4
。
经过适当的拼写更改后,上述几点适用于
utf8mb4
。展望未来,utf8mb4
和 utf8mb4_unicode_520_ci
是首选。或者(8.0 中)utf8mb4_0900_ai_ci
接受的答案已过时。
如果您使用 MySQL 5.5.3+,请使用
utf8mb4_unicode_ci
而不是 utf8_unicode_ci
以确保用户输入的字符不会出现错误。
例如,utf8mb4
支持表情符号,而utf8
可能会给您带来数百个与编码相关的错误,例如:
Incorrect string value: ‘\xF0\x9F\x98\x81…’ for column ‘data’ at row 1
真的,我测试了在具有unique索引的列中保存“é”和“e”等值,它们会导致“utf8_unicode_ci”和“utf8_general_ci”上出现重复错误。您只能将它们保存在“utf8_bin”整理列中。
并且 mysql 文档(在 http://dev.mysql.com/doc/refman/5.7/en/charset-applications.html)建议在其示例中设置“utf8_general_ci”排序规则。
[mysqld]
character-set-server=utf8
collation-server=utf8_general_ci