【问题标题】:mysql utf8mb4_unicode_ci cause unique key collisionmysql utf8mb4_unicode_ci 导致唯一键冲突
【发布时间】:2015-10-30 07:37:52
【问题描述】:

我有一张这样的桌子

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后,问题就消失了。

【问题讨论】:

  • 如果您需要大小写折叠,但需要区分重音,请通过bugs.mysql.com 提出请求。

标签: mysql utf-8 utf8mb4


【解决方案1】:

为什么它们会导致唯一键冲突?它们在 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=Ķ=ķ
  • utf8mb4_unicode_ci 进行更简单的比较。特别是没有 2 字符组合匹配 1 字符编码。确实会发生案例折叠和重音剥离。 K=k=Ķ=ķ
  • utf8mb4_bin 盲目检查位。没有大小写折叠等。K k Ķ ķ 都是不等的。

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

您的 被称为“FULLWIDTH LATIN CAPITAL LETTER K”,因此它与拉丁语K 比较是相当合理的。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-04-15
    • 2019-03-17
    • 1970-01-01
    • 2014-04-06
    • 2010-11-05
    • 1970-01-01
    相关资源
    最近更新 更多