mysql utf8mb4_unicode_ci导致唯一键冲突

时间:2015-08-07 00:33:32

标签: mysql utf-8 utf8mb4

我有一张这样的表

CREATE TABLE `mb1` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `name` varchar(30) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL,
  PRIMARY KEY (`id`),
  UNIQUE KEY `u_name` (`name`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

我插入两行

insert into mb1(name) values('K'),('K');

注意,第二个K是unicode字符

+------+-----------+
| name | hex(name) |
+------+-----------+
| K    | 4B        |
| K   | EFBCAB    |
+------+-----------+

为什么它们会导致唯一的密钥冲突?在utf8mb4中它们不是不同的角色吗?

删除COLLATE utf8mb4_unicode_ci后,问题就消失了。

1 个答案:

答案 0 :(得分:3)

  

为什么它们会导致唯一的密钥冲突?在utf8mb4中它们不是不同的角色吗?

您错过了关于CHARACTER SETCOLLATION的观点。 CHARACTER SET是不同字符的集合。 COLLATION表示是否将字符视为相等 - 请考虑Aa - 不同的字符,但需要ORDER BYWHERE =等处理是一样的。

mysql> SELECT 'K'='K' COLLATE utf8_unicode_ci;
+-----------------------------------+
| 'K'='K' COLLATE utf8_unicode_ci  |
+-----------------------------------+
|                                 1 |
+-----------------------------------+

所以在utf8_unicode_ci(或utf8mb4_unicode_ci)中,这两个字符被认为是“相等的”。

“Equal”是UNIQUE键的测试。

将列的COLLATION设置为适合您的任何内容。

  • utf8mb4_unicode_ci 进行良好的“现实生活”比较,显然包括这一点。 K = k = k = K
  • utf8mb4_unicode_ci ,用于更简单的比较。特别是没有2个字符的组合匹配1个字符的编码。案例折叠和重点剥离确实发生。 K = k = k = K
  • utf8mb4_bin 盲目检查这些位。没有案例折叠等K kĶķ都是不平等的。

utf8mb4_latvian_ci有点不同:K = k但不等于Ķ=ķ。其他语言(主要是西欧语言)还有其他专门的排序规则。

您的被称为“FULLWIDTH LATIN CAPITAL LETTER K”,所以它与拉丁语K相比是非常合理的。