我正在试图弄清楚我应该为各种类型的数据使用哪种排序规则。我将存储的内容的100%是用户提交的。
我的理解是我应该使用UTF-8 General CI(Case-Insensitive)而不是UTF-8 Binary。但是,我无法清楚地区分UTF-8 General CI和UTF-8 Unicode CI。
答案 0 :(得分:289)
一般情况下, 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区分大小写(除其他差异外),因为它会比较字符的二进制值。
答案 1 :(得分:87)
你还应该注意这样一个事实:当使用varchar字段作为唯一或主要索引时,使用utf8_general_ci插入2个值,如'a'和'á'会产生重复键错误。
答案 2 :(得分:26)
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排序规则相同的详细信息,请参阅collation chart。
utf8
,由MySQL 定义的仅限于1到3字节的utf8代码。这遗漏了表情符号和一些中文。所以,如果你想要超越欧洲,你应该切换到utf8mb4
。
在适当的拼写更改后,以上几点适用于utf8mb4
。展望未来,首选utf8mb4
和utf8mb4_unicode_520_ci
。
答案 3 :(得分:6)
真的,我在唯一索引的列中测试了像'é'和'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
答案 4 :(得分:2)
接受的答案已过时。
如果您使用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