utf - 8:将军?本吗?Unicode吗?

我试图弄清楚我应该对各种类型的数据使用什么排序规则。100%的内容,我将存储是用户提交的。

我的理解是我应该使用UTF-8通用CI(不区分大小写)而不是UTF-8二进制。然而,我找不到UTF-8通用CI和UTF-8 Unicode CI之间的明确区别。

  1. 我应该在UTF-8通用列或UTF-8 Unicode CI列中存储用户提交的内容吗?
  2. UTF-8二进制适用于什么类型的数据?
173661 次浏览

一般来说,utf8_general_ciutf8_unicode_ci快,但不太正确。

区别在于:

对于任何Unicode字符集,使用_general_ci排序规则执行的操作比使用_unicode_ci排序规则执行的操作快。例如,与utf8_unicode_ci相比,比较utf8_general_ci排序更快,但稍差一些。这样做的原因是utf8_unicode_ci支持扩展等映射;也就是说,当一个字符与其他字符的组合比较相等时。例如,在德语和其他一些语言中,“ß”等于“ss”。Utf8_unicode_ci还支持缩写和可忽略字符。Utf8_general_ci是一个遗留排序规则,不支持展开、收缩或可忽略字符。它只能在字符之间进行一对一的比较。

< p >引用: http://dev.mysql.com/doc/refman/5.0/en/charset-unicode-sets.html < / p > 更详细的解释,请阅读下面的帖子从MySQL论坛: http://forums.mysql.com/read.php?103,187048,188748 < / p >

对于utf8_bin: utf8_general_ciutf8_unicode_ci都执行不区分大小写的比较。相比之下,Utf8_bin区分大小写(在其他差异中),因为它比较字符的二进制值

您还应该意识到这样一个事实,使用utf8_general_ci时,使用varchar字段作为唯一索引或主索引,插入像'a'和'á'这样的2个值将会给出重复的键错误。

真的,我在独特的索引列中测试了像'é'和'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
  • utf8_bin盲目地比较比特。没有折叠,没有重音剥离。
  • utf8_general_ci比较一个码点和一个码点。它执行case折叠而且重音剥离,但不进行2个字符的比较;例如:在这个排序规则中ij不等于ij
  • utf8_*_ci是一组特定于语言的规则,但在其他方面类似于unicode_ci。一些特殊情况:ÇČchll
  • utf8_unicode_ci遵循旧的Unicode比较标准。ij=ij,但是ae != æ
  • utf8_unicode_520_ci遵循更新的Unicode标准。__abc1 = __abc2

有关各种utf8排序规则中what等于what的详细信息,请参阅排序表

utf8由MySQL定义仅限于1- 3字节的utf8代码。这里省略了Emoji和一些中文。所以如果你想去欧洲以外的地方,你真的应该换成utf8mb4

经过适当的拼写更改后,以上几点适用于utf8mb4。以后,utf8mb4utf8mb4_unicode_520_ci是首选。

  • Utf16和utf32是utf8的变体;它们实际上毫无用处。
  • ucs2更接近“统一码”;比“utf8";它实际上没有任何用处。

公认的答案已经过时了。

如果您使用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