不是重复的,但仍然违反完整性约束:1062 重复条目

问题描述 投票:0回答:1

我正在使用 MySQL(版本 8.0.32)

我有一个表,其架构如下所示:

CREATE TABLE `players` (
  `id` bigint UNSIGNED NOT NULL,
  `name` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL,
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;

具有以下索引:

ALTER TABLE `players`
  ADD PRIMARY KEY (`id`),
  ADD UNIQUE KEY `players_name_unique` (`name`),
ALTER TABLE `players` ADD FULLTEXT KEY `players_name_fulltext` (`name`);

已经有以下几行:

id 名字
1 🅲🅷🅰🆁🅾🅽
2 吉姆

当我去运行以下查询时:

UPDATE `players` SET `name` = '𝓜𝓤𝓡𝓓𝓐𝓗' WHERE id = 2

我收到以下错误:

违反完整性约束:1062 重复条目“??????”对于关键的“players.players_name_unique”

为什么 MySQL 认为以下名称是相同的,或者更确切地说,彼此不唯一:

𝓜𝓤𝓡𝓓𝓐𝓗
🅲🅷🅰🆁🅾🅽

我真的很困惑,不知道如何解决这个问题?难道我做错了什么?我应该使用不同的字符集吗?

谢谢您的帮助

mysql character-encoding
1个回答
0
投票

我有限的理解是,其中一些字符不在 UCA 4.0.0 中,它是在 *_unicode_ci 排序规则中实现的。所有字符都存在于 UCA 9.0.0 中,因此您应该可以使用默认的 utf8mb4_0900_ai_ci 排序规则。

来自 MySQL 文档(Unicode 排序算法 (UCA) 版本):

MySQL 根据 http://www.unicode.org/reports/tr10/ 中描述的 Unicode 排序算法 (UCA) 实现 xxx_unicode_ci 排序规则。该排序规则使用版本 4.0.0 UCA 权重键:http://www.unicode.org/Public/UCA/4.0.0/allkeys-4.0.0.txt

xxx_unicode_ci
排序规则仅部分支持 Unicode 排序规则算法。不支持某些字符,并且不完全支持组合标记。这会影响越南语、约鲁巴语和纳瓦霍语等语言。在字符串比较中,组合字符被视为与使用单个 unicode 字符编写的相同字符不同,并且这两个字符被视为具有不同的长度(例如,由
CHAR_LENGTH()
函数返回或在结果集元数据中返回) ).

基于 UCA 版本高于 4.0.0 的 Unicode 排序规则在排序规则名称中包含版本。例子:

字符 角色名称 UCA 4.0.0 UCA 5.2.0 UCA 9.0.0
🅲 负平方拉丁文大写字母 C U+1F172
🅷 负平方拉丁文大写字母 H U+1F177
🅰 负平方拉丁文大写字母 A U+1F170
🆁 负平方拉丁文大写字母 R U+1F181
🅾 负平方拉丁文大写字母 O U+1F17E
🅽 负平方拉丁文大写字母 N U+1F17D
𝓜 数学粗体字母大写 M U+1D4DC
𝓤 数学粗体字母大写 U U+1D4E4
𝓡 数学粗体字母大写 R U+1D4E1
𝓓 数学粗体字母大写 D U+1D4D3
𝓐 数学粗体字母大写 A U+1D4D0
𝓗 数学粗体字母大写 H U+1D4D7
SET @string1 = '𝓜𝓤𝓡𝓓𝓐𝓗' COLLATE utf8mb4_0900_ai_ci;
SET @string2 = '🅲🅷🅰🆁🅾🅽' COLLATE utf8mb4_0900_ai_ci;

SELECT *
FROM (
    VALUES
        ROW(@string1, @string2, 'utf8mb4_unicode_ci', @string1 COLLATE utf8mb4_unicode_ci = @string2 COLLATE utf8mb4_unicode_ci),
        ROW(@string1, @string2, 'utf8mb4_unicode_520_ci', @string1 COLLATE utf8mb4_unicode_520_ci = @string2 COLLATE utf8mb4_unicode_520_ci),
        ROW(@string1, @string2, 'utf8mb4_0900_ai_ci', @string1 COLLATE utf8mb4_0900_ai_ci = @string2 COLLATE utf8mb4_0900_ai_ci),
        ROW(@string1, @string2, 'utf8mb4_da_0900_as_cs', @string1 COLLATE utf8mb4_da_0900_as_cs = @string2 COLLATE utf8mb4_da_0900_as_cs)
) AS x (`@string1`, `@string2`, `collation`, `equal`);

输出:

@string1 @string2 整理 平等
𝓜𝓤𝓡𝓓𝓐𝓗 🅲🅷🅰🆁🅾🅽 utf8mb4_unicode_ci 1
𝓜𝓤𝓡𝓓𝓐𝓗 🅲🅷🅰🆁🅾🅽 utf8mb4_unicode_520_ci 0
𝓜𝓤𝓡𝓓𝓐𝓗 🅲🅷🅰🆁🅾🅽 utf8mb4_0900_ai_ci 0
𝓜𝓤𝓡𝓓𝓐𝓗 🅲🅷🅰🆁🅾🅽 utf8mb4_da_0900_as_cs 0

我无法解释为什么当排序规则中不存在

utf8mb4_unicode_520_ci
字符时,
Negative Squared Latin Capital Letter
认为两个字符串不同。"希望有更好理解的人能够解释为什么排序规则中不存在的字符在 � 75e1 ��utf8mb4_unicode_ci
utf8mb4_unicode_520_ci
 之间的处理方式不同。
\n "

© www.soinside.com 2019 - 2024. All rights reserved.