2016-01-25 2 views
0

Remarque: Dans la question suivante, vous pouvez voir? ou des blocs au lieu de caractères, c'est parce que vous n'avez pas la police appropriée. S'il vous plaît ignorer cela.MySQL renvoie des caractères étendus UTF8 incorrects dans certains cas seulement

Contexte

J'ai une table avec des données structurées comme suit:

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 

Et quelques exemples de données:

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

Et les jeux de caractères sont tous réglés correctement:

enter image description here

Problème

Il est très important de noter que:

Comme vous pouvez le voir, ce sont des caractères différents. Cependant, dans certains cas, ils sont traités comme le même caractère.

Cas 1

Quand je lance la requête suivante, il ne retourne que l'enfant correct (c.-à-ne retourne pas la même apparence, mais un enfant différent de caractères):

SELECT * 
FROM decomposition_dup 
WHERE parent = '锦' 

enter image description here

Ce comportement est correct.

Cas n ° 2

Cependant, quand je lance la requête suivante à l'aide 钅 (http://unicode.scarfboy.com/?s=%E9%92%85), elle retourne les deux personnages similaires:

SELECT * 
FROM decomposition_dup 
WHERE parent = '钅' 

enter image description here

Cela ne devrait revenir 185775, 185774 & 21195.

Cas 3

Et quand je lance la requête suivante à l'aide ⻐ (http://unicode.scarfboy.com/?s=%E2%BB%90), il retourne aussi les deux personnages similaires:

SELECT * 
FROM decomposition_dup 
WHERE parent = '⻐' 

enter image description here

Cela ne devrait revenir 21178 et 21177.

Cas 4

Si je remplace = avec LIKE pour les requêtes brisées (à savoir le cas 2 et 3 cas), ils reviennent correctement.

Par exemple, la requête suivante est le même que le cas 3, mais en utilisant LIKE:

SELECT * 
FROM decomposition_dup 
WHERE parent LIKE '⻐' 

enter image description here

Cela renvoie les caractères corrects mais ralentit la requête.

Question

Est-ce un bogue dans MySQL ou est-il quelque chose que je méconnais lors de l'interrogation des caractères étendus UTF8?

Répondre

1

Si vous voulez qu'ils soient les mêmes, régler la COLLATION des colonnes à utf8mb4_unicode_ci ou utf8mb4_unicode_520_ci.
Si vous voulez qu'ils soient différents, utilisez utf8mb4_general_ci, à la place:

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 | 
+-------------+ 
+0

Je vais essayer cela quand je rentre du travail, mais d'après ce que j'ai lu utf8mb4_unicode_ci différencie le plus précisément entre les caractères - très étrange! (http://stackoverflow.com/questions/766809/whats-the-difference-between-utf8-general-ci-and-utf8-unicode-ci) –

+0

Oh mais dans ce cas 'utfmb4_general_ci' résout le problème de la différenciation correcte entre les caractères e99285 et e2bb90, non? –

+0

Merci, cas fermé! C'était un problème d'encodage. –

-1

D'après ce que je peux faire le problème se trouve dans le côté SQL des choses sur la recherche, vous verrez que ce code d'erreur signifie que

permis de UTF8 de MySQL uniquement les caractères Unicode qui peuvent être représentés par 3 octets en UTF-8.

Il pourrait donc être les caractères que vous utilisez dans les cas de SQL

+1

Pour ce code d'erreur vous faites référence? Et à partir de MySQL 5.5.3, le jeu de caractères utf8mb4 utilise un maximum de quatre octets par caractère et supporte les caractères supplémentaires –

+0

Les spécificités de ce thread fonctionnent de la même manière dans utf8 et utf8mb4. utf8mb4 est un meilleur choix pour le chinois, Emoji et certaines applications/langues moins courantes. –