Différents opérateurs
LIKE
et =
sont différents opérateurs. La plupart des réponses se concentrent ici sur le support des caractères génériques, ce qui n'est pas la seule différence entre ces opérateurs!
=
est un opérateur de comparaison qui opère sur des nombres et des chaînes. Lors de la comparaison de chaînes, l'opérateur de comparaison compare des chaînes entières .
LIKE
est un opérateur de chaîne qui compare caractère par caractère .
Pour compliquer les choses, les deux opérateurs utilisent un classement qui peut avoir des effets importants sur le résultat de la comparaison.
Exemple de motivation
Identifions d'abord un exemple où ces opérateurs produisent des résultats évidemment différents. Permettez-moi de citer le manuel MySQL:
Selon le standard SQL, LIKE effectue la correspondance par caractère, il peut donc produire des résultats différents de l'opérateur de comparaison =:
mysql> SELECT 'ä' LIKE 'ae' COLLATE latin1_german2_ci;
+-----------------------------------------+
| 'ä' LIKE 'ae' COLLATE latin1_german2_ci |
+-----------------------------------------+
| 0 |
+-----------------------------------------+
mysql> SELECT 'ä' = 'ae' COLLATE latin1_german2_ci;
+--------------------------------------+
| 'ä' = 'ae' COLLATE latin1_german2_ci |
+--------------------------------------+
| 1 |
+--------------------------------------+
Veuillez noter que cette page du manuel MySQL est appelée Fonctions de comparaison de chaînes et =
n'est pas discutée, ce qui implique qu'il =
ne s'agit pas strictement d'une fonction de comparaison de chaînes.
Comment ça =
marche?
Le SQL Standard § 8.2 décrit comment =
compare les chaînes:
La comparaison de deux chaînes de caractères est déterminée comme suit:
a) Si la longueur en caractères de X n'est pas égale à la longueur en caractères de Y, alors la chaîne la plus courte est effectivement remplacée, à des fins de comparaison, par une copie d'elle-même qui a été étendue à la longueur de la chaîne la plus longue par concaténation à droite d'un ou plusieurs caractères de pad, où le caractère de pad est choisi en fonction de CS. Si CS a l'attribut NO PAD, alors le caractère de remplissage est un caractère dépendant de l'implémentation différent de n'importe quel caractère dans le jeu de caractères de X et Y qui rassemble moins que n'importe quelle chaîne sous CS. Sinon, le caractère du tampon est a.
b) Le résultat de la comparaison de X et Y est donné par la séquence de classement CS.
c) Selon la séquence d'assemblage, deux chaînes peuvent se comparer comme égales, même si elles sont de longueurs différentes ou contiennent des séquences de caractères différentes. Lorsque les opérations MAX, MIN, DISTINCT, des références à une colonne de regroupement et les opérateurs UNION, EXCEPT et INTERSECT font référence à des chaînes de caractères, la valeur spécifique sélectionnée par ces opérations dans un ensemble de ces valeurs égales dépend de l'implémentation.
(Je souligne.)
Qu'est-ce que ça veut dire? Cela signifie que lors de la comparaison de chaînes, l' =
opérateur n'est qu'un mince wrapper autour du classement actuel. Un classement est une bibliothèque qui a différentes règles pour comparer des chaînes. Voici un exemple de classement binaire de MySQL :
static int my_strnncoll_binary(const CHARSET_INFO *cs __attribute__((unused)),
const uchar *s, size_t slen,
const uchar *t, size_t tlen,
my_bool t_is_prefix)
{
size_t len= MY_MIN(slen,tlen);
int cmp= memcmp(s,t,len);
return cmp ? cmp : (int)((t_is_prefix ? len : slen) - tlen);
}
Ce classement particulier arrive à comparer octet par octet (c'est pourquoi il est appelé "binaire" - il ne donne aucune signification particulière aux chaînes). D'autres classements peuvent fournir des comparaisons plus avancées.
Par exemple, voici un classement UTF-8 qui prend en charge les comparaisons non sensibles à la casse. Le code est trop long pour être collé ici, mais allez sur ce lien et lisez le corps de my_strnncollsp_utf8mb4()
. Ce classement peut traiter plusieurs octets à la fois et il peut appliquer diverses transformations (telles que la comparaison insensible à la casse). L' =
opératrice est complètement abstraite des aléas de la collation.
Comment ça LIKE
marche?
Le SQL Standard § 8.5 décrit comment LIKE
compare les chaînes:
Le <prédicat>
M LIKE P
est vrai s'il existe un partitionnement de M en sous-chaînes tel que:
i) Une sous-chaîne de M est une séquence de 0 ou plusieurs <représentation de caractère> contiguës de M et chaque <représentation de caractère> de M fait partie d'exactement une sous-chaîne.
ii) Si le i-ième spécificateur de sous-chaîne de P est un spécificateur de caractère arbitraire, la i-ième sous-chaîne de M est n'importe quelle <représentation de caractère>.
iii) Si le i-ième spécificateur de sous-chaîne de P est un spécificateur de chaîne arbitraire, alors la i-ième sous-chaîne de M est une séquence de 0 ou plus <représentation de caractère> s.
iv) Si le i-ème spécificateur de sous-chaîne de P n'est ni un spécificateur de caractère arbitraire ni un spécificateur de chaîne arbitraire, alors la i-ème sous-chaîne de M est égale à ce spécificateur de sous-chaîne selon la séquence de classement du <prédicat similaire>, sans l'ajout de caractères <espace> à M, et a la même longueur que ce spécificateur de sous-chaîne.
v) Le nombre de sous-chaînes de M est égal au nombre de spécificateurs de sous-chaînes de P.
(Je souligne.)
C'est assez verbeux, alors décomposons-le. Les éléments ii et iii font respectivement référence aux caractères génériques _
et %
. Si P
ne contient aucun caractère générique, seul l'élément iv s'applique. C'est le cas d'intérêt posé par le PO.
Dans ce cas, il compare chaque "sous-chaîne" (caractères individuels) à M
chaque sous-chaîne en P
utilisant le classement actuel.
Conclusions
L'essentiel est que lors de la comparaison de chaînes, =
compare la chaîne entière tout en LIKE
comparant un caractère à la fois. Les deux comparaisons utilisent le classement actuel. Cette différence conduit à des résultats différents dans certains cas, comme en témoigne le premier exemple de ce post.
Lequel devriez-vous utiliser? Personne ne peut vous le dire - vous devez utiliser celui qui convient à votre cas d'utilisation. N'optimisez pas prématurément en changeant d'opérateurs de comparaison.