【发布时间】:2023-04-09 12:47:01
【问题描述】:
在表x 中,有一列的值是u 和ü。
SELECT * FROM x WHERE column='u'.
这将返回 u AND ü,尽管我只是在寻找 u。
表格的排序规则是 utf8mb4_unicode_ci 。无论我在哪里读到类似的问题,每个人都建议使用这种排序规则,因为他们说utf8mb4 确实涵盖了所有字符。使用这种排序规则,应该可以解决所有字符集和排序规则问题。
我可以插入ü、è、é、à、Chinese characters等。当我创建SELECT *时,它们也被正确检索和显示。
仅当我比较两个字符串时,如上例 (SELECT WHERE) 或当我在列上使用 UNIQUE INDEX 时,才会出现此问题。当我使用UNIQUE INDEX 时,当我在列中已有"u" 时,不会插入"ü"。所以,当SQL比较u和ü以确定ü是否唯一时,它认为它与u相同,并没有插入ü。
我将所有内容都更改为utf8mb4,因为我不想再担心字符集和排序规则了。但是,在比较字符串时,utf8mb4 似乎也不是解决方案。
我也试过这个:
SELECT * FROM x WHERE _utf8mb4 'ü' COLLATE utf8mb4_unicode_ci = column。
这段代码是可执行的(看起来很复杂)。但是,它也返回 ü AND u。
我已经与印度和中国的一些人讨论过这个问题。我们还没有找到解决方案。
如果有人能解开这个谜,那就太好了。
Add_On:看完下面的所有答案和cmets,下面是一个解决问题的代码示例:
SELECT * FROM x WHERE 'ü' 整理 utf8mb4_bin = column
通过在 SELECT 查询中添加“COLLATE utf8mb4_bin”,SQL 在查看列中的字符时被邀请戴上“二进制眼镜”(结尾为 _bin)。戴上二进制眼镜后,SQL 现在可以看到列中的二进制代码。并且对于每个可以想到的字母和字符以及表情符号,二进制代码都是不同的。因此,SQL 现在也可以看到 u 和 ü 之间的区别。因此,现在它只在 SELECT 查询查找 ü 时返回 ü,而不返回 u。
通过这种方式,可以保持所有内容(数据库排序规则、表排序规则)相同,但仅在需要精确区分时将“COLLATE utf8mb4_bin”添加到查询中。
(实际上,SQL 摘下了所有其他眼镜(utf8mb4_german_ci、_general_ci、_unicode_ci 等),并且仅在不强制执行任何其他操作时执行它所做的事情。它只是查看二进制代码而不调整其搜索任何特殊的文化背景。)
感谢大家的支持,尤其是 Pred。
【问题讨论】:
-
从您的描述来看,您似乎确实想要忽略排序规则并执行二进制匹配。你的具体规则是什么?例如,
u和U应该被视为相同还是不同? -
嗨,阿尔瓦罗。过去我在 stackoverflow 上花了很多时间。但是,我从未发布过问题。反应是压倒性的。 Stackoverflow 似乎是一条通往解决方案的道路。最好的办法是:在比较期间(WHERE 或 UNIQUE),在行中显示不同的所有内容在比较期间也会有所不同。所以,ä 不是 a。 a 不是 A。è 不是 e 等。如果二进制区分所有这些,那可能就是要走的路。我可以在查询期间进行区分而其他一切都保持不变吗?解决这个问题的实用方法是什么?
-
嗨,阿尔瓦罗。您还询问规则: 1. 它应该是我完全理解的可预测的解决方案。 2. 如果可能,它应该在许多不同的环境中工作。 3. 如果可能的话,应该是一个简单的解决方案。 4. 如果可能的话,它应该很快(现在不是那么重要)。然而,最重要的是:它应该是完全可预测的,并且易于理解和处理。
-
谢谢,阿尔瓦罗。在阅读了 Pred 下面写的内容后,我也理解了你的回答。是的,这一切的核心是用户对其文化背景的期望。谢谢。
标签: mysql sql utf-8 utf utf8mb4