仅在某些情况下,MySQL才返回不正确的UTF8扩展字符 [英] MySQL returns incorrect UTF8 extended characters in some cases only

查看:96
本文介绍了仅在某些情况下,MySQL才返回不正确的UTF8扩展字符的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

注意:在下面的问题中,您可能会看到?或块而不是字符,这是因为您没有适当的字体。请忽略此操作。

背景

我有一个表,其中的数据结构如下:

CREATE TABLE `decomposition_dup` (
 `id` int(11) NOT NULL AUTO_INCREMENT,
 `parent` varchar(50) COLLATE utf8mb4_unicode_ci NOT NULL,
 `structure` varchar(50) COLLATE utf8mb4_unicode_ci NOT NULL,
 `child` varchar(50) COLLATE utf8mb4_unicode_ci NOT NULL,
 PRIMARY KEY (`id`),
 KEY `parent` (`parent`),
 KEY `child` (`child`),
 KEY `parent_2` (`parent`,`child`)
) ENGINE=InnoDB AUTO_INCREMENT=211929 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci

和一些示例数据:

INSERT INTO `decomposition_dup` (`id`, `parent`, `structure`, `child`) VALUES
(154647, '锦', 'a', '钅'),
(154648, '锦', 'a', '帛'),
(185775, '钅', 'd', '二'),
(185774, '钅', 'd', '㇟'),
(21195, '钅', 'd', '𠂉'),
(21178, '⻐', 'd', '乇'),
(21177, '⻐', 'd', '𠂉');

且字符集均设置正确:

问题

请注意非常重要的一点:

如您所见,它们是不同的字符。但是,在某些情况下,它们被视为相同的字符

案例1

当我运行以下查询时,它只返回正确的子项(即不返回外观相似但字符不同的子项):

SELECT *
FROM decomposition_dup
WHERE parent = '锦'

这是正确的行为。

案例2

但是,当我使用钅(http://unicode.scarfboy.com/?s=%E9%92%85)运行以下查询时,它返回两个相似的字符:

SELECT *
FROM decomposition_dup
WHERE parent = '钅'

这应该只返回185775、185774和amp;21195。

案例3

当我使用⻐(http://unicode.scarfboy.com/?s=%E2%BB%90)运行以下查询时,它也返回两个相似的字符:

SELECT *
FROM decomposition_dup
WHERE parent = '⻐'

这应该只返回21178和21177。

案例4

如果我将断开的查询(即案例2和案例3)的=替换为LIKE,它们将正确返回。

例如,以下查询与案例3相同,但使用LIKE

SELECT *
FROM decomposition_dup
WHERE parent LIKE '⻐'

这将返回正确的字符,但会减慢查询速度。

问题

这是MySQL中的错误,还是我在查询UTF8扩展字符时忽略了什么?

推荐答案

如果希望它们相同,请将列的COLLATION设置为utf8mb4_unicode_ciutf8mb4_unicode_520_ci
如果希望它们不同,请使用utf8mb4_general_ci,而不是:

mysql> SELECT CONVERT(UNHEX('e99285') USING utf8mb4) =
    ->        CONVERT(UNHEX('e2bb90') USING utf8mb4) COLLATE utf8mb4_general_ci AS general;
+---------+
| general |
+---------+
|       0 |
+---------+

mysql> SELECT CONVERT(UNHEX('e99285') USING utf8mb4) =
    ->        CONVERT(UNHEX('e2bb90') USING utf8mb4) COLLATE utf8mb4_unicode_ci AS unicode;
+---------+
| unicode |
+---------+
|       1 |
+---------+

mysql> SELECT CONVERT(UNHEX('e99285') USING utf8mb4) =
    ->        CONVERT(UNHEX('e2bb90') USING utf8mb4) COLLATE utf8mb4_unicode_520_ci AS unicode_520;
+-------------+
| unicode_520 |
+-------------+
|           1 |
+-------------+

这篇关于仅在某些情况下,MySQL才返回不正确的UTF8扩展字符的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆