簡體   English   中英

MySQL僅在某些情況下返回不正確的UTF8擴展字符

[英]MySQL returns incorrect UTF8 extended characters in some cases only

注意:在以下問題中,您可能會看到? 或塊而不是字符,這是因為您沒有適當的字體。 請忽略此。

背景

我有一個數據結構如下的表:

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', '𠂉');

字符集都正確設置:

在此處輸入圖片說明

問題

務必注意

  • 154647、185775、185774和21195引用此字符: http ://unicode.scarfboy.com/?s=%E9%92%85
  • 21178和21177引用此字符: http ://unicode.scarfboy.com/?s=%E2%BB%90

如您所見,它們是不同的字符。 但是,在某些情況下,它們被視為相同的字符

情況1

當我運行以下查詢時,它僅返回正確的子代(即不返回外觀相似但字符不同的子代):

SELECT *
FROM decomposition_dup
WHERE parent = '錦'

在此處輸入圖片說明

這是正確的行為。

情況二

但是,當我使用run( http://unicode.scarfboy.com/?s=%E9%92%85 )運行以下查詢時,它將返回兩個相似的字符:

SELECT *
FROM decomposition_dup
WHERE parent = '釒'

在此處輸入圖片說明

這只會返回185775、185774和21195。

情況3

當我使用run( http://unicode.scarfboy.com/?s=%E2%BB%90 )運行以下查詢時,它還會返回兩個相似的字符:

SELECT *
FROM decomposition_dup
WHERE parent = '⻐'

在此處輸入圖片說明

這應該只返回21178和21177。

案例4

如果我將LIKE替換= LIKE = (對於案例2和案例3),它們將正確返回。

例如,以下查詢與案例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 |
+-------------+

根據我的判斷,問題出在研究的S​​QL方面,您將看到此錯誤代碼表示

MySQL的utf8僅允許使用UTF-8中的3個字節表示的Unicode字符。

所以這可能是您在SQL中使用的字符

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM