utf8_bin 与 utf_unicode_ci

Posted

技术标签:

【中文标题】utf8_bin 与 utf_unicode_ci【英文标题】:utf8_bin vs. utf_unicode_ci 【发布时间】:2012-06-11 09:22:51 【问题描述】:

我的餐桌网站

Website_Name//column name
Google
Facebook
Twitter
Orkut
Frype
Skype
Yahoo
Wikipedia

我使用 utf8_bin 排序规则,然后我在网站中搜索***的查询是

Select Website_Name from Website where lower(Website_Name)='wikipedia'

如果我使用 utf8_unicode_ci 那么我在网站中搜索***的选择查询是

Select Website_Name from Website where Website_Name='wikipedia'

现在我想根据以下查询知道哪种排序规则最好

【问题讨论】:

【参考方案1】:

这取决于你需要什么。

utf8_bin 排序规则纯粹根据其 Unicode code point 值比较字符串。如果所有代码点都具有相同的值,则字符串相等。但是,当您有用于组合标记(组合与分解)的字符串具有不同组合的字符串或规范等效但不具有相同代码点值的字符时,这就会分崩离析。在某些情况下,使用utf8_bin 会导致字符串与您期望的不匹配。从理论上讲,utf8_bin 是最快的,因为没有对字符串应用 Unicode 规范化,但它可能不是您想要的。

utf8_general_ci 使用特定于语言的规则应用 Unicode 规范化,并且不区分大小写地比较字符串。 utf8_general_cs 做同样的事情,但区分大小写比较字符串。

【讨论】:

所以我用的是什么。要具体 正如我所说,您应该根据自己的需要做出此决定。从我所看到的关于你想要做的事情来看,我自己会选择utf8_general_ci 在utf8_bin中使用lower()有什么缺点吗 虽然在英语中是一样的,但在某些语言中使用lower() 并不总是与不区分大小写比较相同,使用lower() 比较大小写可能会遇到问题——麻木不仁。我会坚持使用不区分大小写的排序规则。【参考方案2】:

我个人会选择utf8_unicode_ci,如果您认为字母大小写通常对于您想要查找的结果并不重要。

排序规则不仅在运行时使用,而且在 mysql 构建索引时使用。因此,如果这些列中的任何一个出现在索引中,根据该排序规则的比较规则查找数据将几乎与以往一样快。

在您不希望不区分大小写匹配的情况下,请不要应用大写或小写。相反,在 utf8 列前面应用 BINARY 关键字来强制进行文字代码点比较,而不是根据排序规则进行比较。

mysql> create table utf8 (name varchar(24) charset utf8 collate utf8_general_ci, primary key (name));
Query OK, 0 rows affected (0.14 sec)

mysql> insert into utf8 values ('Roland');
Query OK, 1 row affected (0.00 sec)

mysql> insert into utf8 values ('roland');
ERROR 1062 (23000): Duplicate entry 'roland' for key 'PRIMARY'
mysql> select * from utf8 where name = 'roland';
+--------+
| name   |
+--------+
| Roland |
+--------+
1 row in set (0.00 sec)

mysql> select * from utf8 where binary name = 'roland';
Empty set (0.01 sec)

这应该比使用 lower 或 upper 快得多,因为在这些情况下,MySQL 首先需要复制列值并修改其字母大小写,然后应用比较。使用 BINARY 后,它将首先使用索引来查找匹配项,然后逐个代码点进行比较,直到发现值不相等,这通常会更快。

【讨论】:

我的经验只是提醒一下;当行为utf8_general_ci 时,使用WHERE BINARYCOLLATE utf8_bin 会对使用PRIMARY KEY 的查询产生负面的性能影响。在 MySQL 5.6.22 和 5.6.10 上测试。直到数据库处于适当的负载下,问题才会出现。【参考方案3】:

我使用的是默认的“utf8_unicode_ci”,我不得不将其更改为:

 * @ORM\Table(name = "Table", options="collate"="utf8_bin")

因为我的一些复合主键由文本字段组成。可悲的是,'utf8_unicode_ci' 将“poistný”和“poistny”解析为相同的主键值,并以插入刷新的原则崩溃而告终。我不能简单地更改复合主键的一部分的排序规则,必须删除表并重新创建。希望它可以节省其他人的时间..

【讨论】:

这篇文章utf8_unicode_ci vs utf8_general_ci解释了utf8_unicode_ciutf8_general_ci之间的区别

以上是关于utf8_bin 与 utf_unicode_ci的主要内容,如果未能解决你的问题,请参考以下文章

phpmyadmin 为 mysql utf8_bin 排序列显示数字或 blob?

utf8_bin跟utf8_general_ci的区别

MySQL_编码utf8_bin和utf8_general_ci的区别

MySQL系列:utf8_bin和utf8_general_ci编码的区别

SQLalchemy使用补充

建库和建表中编码问题