UTF-8:一般?斌吗 Unicode?


279

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

我的理解是,我应该使用UTF-8 General CI(不区分大小写),而不是UTF-8 Binary。但是,我找不到UTF-8通用CI和UTF-8 Unicode CI之间的明显区别。

  1. 我应该将用户提交的内容存储在UTF-8 General或UTF-8 Unicode CI列中吗?
  2. UTF-8 Binary适用于什么类型的数据?

16
旁注,而不是utf8utf8mb4而是使用以获得完整的UTF-8支持。在此发表评论是因为此热门问题的答案无法解决。mathiasbynens.be/notes/mysql-utf8mb4
Steven R. Loomis

如果要折叠大小写但要注意重音,请在bugs.mysql.com上提出请求。
瑞克·詹姆斯

或在bugs.mysql.com/bug.php?id=58797上单击“影响我” 并添加评论。
里克·詹姆斯

Answers:


299

通常,utf8_general_ciutf8_unicode_ci快,但正确性较差。

区别在于:

对于任何Unicode字符集,使用_general_ci排序规则执行的操作都比_unicode_ci排序规则执行的操作更快。例如,utf8_general_ci归类的比较比utf8_unicode_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_ciutf8_unicode_ci都执行不区分大小写的比较。相反,utf8_bin区分大小写(除其他差异外),因为它比较字符的二进制值。


2
我认为,如果您没有充分的理由使用_unicode_ci,请使用_general_ci。
Sagi 2010年

4
但是,这实际上并不能真正回答问题。这些归类之间到底有什么区别?
Pekka

4
没错,为简单起见,此处未提供确切的区别。我添加了一个链接,该链接具有确切的区别。
Sagi

NB show collation;允许您查看每个字符集的默认排序规则。utf8_general_ci默认显示5.1 utf8
大卫·卡波尼

9
是否有任何资源可以对两个排序规则之间的实际速度差异进行更深入的研究?我们是在谈论性能下降0.1%还是下降10%?
Emphram Stavanger 2013年

90

您还应该意识到以下事实:使用utf8_general_ci将varchar字段用作唯一索引或主索引时,插入2个值(例如“ a”和“á”)会产生重复的键错误。


3
谢谢,这对于避免类似的用户名很有用(例如,如果存在“ jose”,我不想让其他人创建“josé”用户)注意:这对于大多数utf8归类(utf8_bin除外)也适用。最可靠/最安全/最全面的服务是utf8_unicode_ci
Costa

2
我使用utf8_bin,我希望在索引中区分jose和josé。例如,一列记录了搜索/替换操作,在该列中用户可能决定搜索josé,并将其替换为jose。(我正在编写电子表格程序)
Buttle Butkus,

33
  • utf8_bin盲目比较位。没有外壳折叠,没有重音剥离。
  • utf8_general_ci将一个字节与一个字节进行比较。它确实进行大小写折叠重音剥离,但没有2个字符的比较:ijij在此排序规则中不相等。
  • utf8_*_ci是一组特定于语言的规则,但类似unicode_ci。一些特殊情况:ÇČchll
  • 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是首选。

  • utf16和utf32是utf8的变体;他们几乎没有用。
  • ucs2比“ utf8”更接近“ Unicode”;几乎没有用。

1
关于“敬请关注”:8.0归类显示了8.0 utf8mb4归类中各种字符,diphthongs等的比较情况;utf8大致相同。
瑞克·詹姆斯

8.0排序规则的时钟速度明显快于5.x。
里克·詹姆斯

如果该页面在顶部列出utf8mb4_bin,那就太好了。我知道它根本没有字符匹配,但是对新手来说很好。
Henk Poley19年

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

1
我对此进行了快速测试,它似乎是准确的。当涉及到列上的唯一键和带有波浪号等的值时,两种排序规则的行为相同。
MirroredFate 2015年

@MirroredFate好,我应该在此添加该列应具有导致此错误的唯一索引。它暗示了我的答案。
vitalii

3

接受的答案已过时。

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


该答案(正确)解决了表情符号(和某些中文)的编码问题。但是问题似乎集中在整理上。 utf8mb4_unicode_ci(我认为)所有表情符号都一样。 utf8mb4_unicode_520_ci下订单给表情符号。
瑞克·詹姆斯
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.