不同算子
LIKE和=是不同的操作者。这里的大多数答案都集中在通配符支持上,这并不是这些操作符之间唯一的区别!
=是对数字和字符串进行操作的比较运算符。比较字符串时,比较运算符将整串.
LIKE比较的字符串运算符。逐字逐句.
让事情变得更复杂的是,两个操作符都使用了校对这对比较的结果有重要的影响。
激励实例
让我们首先确定一个例子,其中这些操作符产生明显不同的结果。请允许我引用MySQL手册:根据SQL标准,类似于在每个字符的基础上执行匹配,因此它可以产生与=比较操作符不同的结果:
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 |
+--------------------------------------+
请注意,MySQL手册的这一页名为字符串比较函数,和=没有讨论,这意味着=不是严格意义上的字符串比较函数。
如何=工作?
这个SQL标准§8.2描述如何=比较字符串:两个字符串的比较如下:
(A)如果X的字符长度不等于Y字符的长度,则为比较起见,将较短的字符串有效地替换为其自身的副本,该副本已通过在一个或多个PAD字符的右侧级联扩展到较长字符串的长度,其中基于CS选择PAD字符。如果CS有no pad属性,那么pad字符是一个与实现相关的字符,它不同于X和Y字符集中任何比CS下的任何字符串都要小的字符。否则,衬垫字符是。
(B)用比较序列CS给出了X和Y的比较结果。
c)根据排序顺序的不同,即使两个字符串的长度不同或包含不同的字符序列,它们也可以比较为相等。当操作MAX、MIN、DISTISTION、对分组列的引用以及UNION(除了)和IntersectOperator引用字符串时,这些操作从一组相同值中选择的特定值与实现有关。
(强调后加)
这是什么意思?这意味着当比较字符串时,=运算符只是当前排序规则的一个薄包装器。排序规则是具有比较字符串的各种规则的库。这里有一个例子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);}
这种特殊的排序规则碰巧是逐字节比较的(这就是为什么它被称为“二进制”-它没有赋予字符串任何特殊的意义)。其他排序可能提供更高级的比较。
例如,这里有一个UTF-8校对这支持不区分大小写的比较。代码太长,无法粘贴到这里,但请转到该链接并阅读my_strnncollsp_utf8mb4()..这种排序规则可以一次处理多个字节,并且可以应用各种转换(例如不区分大小写的比较)。这个=运算符是从变化无常的校对中完全抽象出来的。
如何LIKE工作?
这个SQL标准§8.5描述如何LIKE比较字符串:
M LIKE P
如果存在将M划分为子字符串的情况,则为真:
(I)M的子串是M的0或多个连续s的序列,而M的每个都是一个子字符串的一部分。
(Ii)如果P的第一个子字符串说明符是任意字符说明符,则M的第一个子字符串是任意一个。
如果P的第一个子字符串说明符是任意的字符串说明符,那么M的第一个子字符串就是0或更多s的任意序列。
(Iv)如果P的第一个子字符串说明符既不是任意字符说明符,也不是任意字符串说明符,则根据的排序序列,M的第I子字符串等于该子字符串说明符,而不将字符附加到M中,并且与该子字符串说明符具有相同的长度。
(V)M的子串数等于P的子串说明符的个数。
(强调后加)
这句话很冗长,所以让我们把它分解一下吧。第二项和第三项指通配符_和%分别。如果P不包含任何通配符,则只有第四项适用。这就是“任择议定书”提出的令人感兴趣的情况。
在本例中,它比较每个“子字符串”(单个字符)M中的每个子字符串P使用当前排序规则。
结论
底线是当比较字符串时,=比较整个字符串LIKE每次比较一个字符。这两个比较都使用当前排序规则。这种差异在某些情况下会导致不同的结果,正如本文的第一个例子所证明的那样。
你应该用哪一种?没有人能告诉你-你需要用正确的用例。不要过早地通过切换比较操作符来优化。