如果我必须找到一个字符串名称"Akito"并且它位于表foo中,那么下面是正常过程,
"Akito"
select * from foo where `name = 'Akito'`
我试图检查它的两个变体,
工作正常
select * from foo where name = 'Akito '
没有正常工作
select * from foo where name = ' Akito'
谁能解释一下第二个为什么不起作用?
提前致谢
CHAR类型 使用空字节 将字符串填充到字段的长度(而VARCHAR添加定界符以指示字符串的末尾-因此忽略了末尾的额外数据( 我的意思是空字节 )),因此,在字符串末尾有空格的比较最终将忽略那些。前导空格很重要,因为它们会改变字符串本身。参见克里斯托弗的答案。
编辑:需要进一步的阐述
请参阅下面的一些实际测试。VARCHAR类型的确会在字符串中添加空格,而CHAR字段(即使它们使用空格填充了字符串的大小)也会在比较期间忽略它们。具体参见LENGTH函数查询的第二行:
LENGTH
mysql> create table test (a VARCHAR(10), b CHAR(10)); Query OK, 0 rows affected (0.17 sec) mysql> insert into test values ('a', 'a'), ('a ', 'a '), (' a', ' a'); Query OK, 3 rows affected (0.00 sec) Records: 3 Duplicates: 0 Warnings: 0 mysql> select a, LENGTH(a), b, LENGTH(b) FROM test; +------+-----------+------+-----------+ | a | LENGTH(a) | b | LENGTH(b) | +------+-----------+------+-----------+ | a | 1 | a | 1 | | a | 2 | a | 1 | | a | 2 | a | 2 | +------+-----------+------+-----------+ 3 rows in set (0.00 sec)
MySQL声明的CHAR字段的长度为1个字符,其插入时的值为’a’。此外,如果我们连接一些数据:
mysql> select CONCAT(a, '.'), CONCAT(b, '.') FROM test; +----------------+----------------+ | CONCAT(a, '.') | CONCAT(b, '.') | +----------------+----------------+ | a. | a. | | a . | a. | | a. | a. | +----------------+----------------+ 3 rows in set (0.00 sec) mysql> select CONCAT(a, b), CONCAT(b, a) FROM test; +--------------+--------------+ | CONCAT(a, b) | CONCAT(b, a) | +--------------+--------------+ | aa | aa | | a a | aa | | a a | a a | +--------------+--------------+ 3 rows in set (0.00 sec)
您会看到,由于VARCHAR确实存储了字符串的结束位置,因此空格保留在串联上- 对于CHAR类型而言,这不成立。现在,请记住前面的LENGTH示例,其中第二行的字段a和b具有不同的长度,我们测试:
mysql> SELECT * FROM test WHERE a=b; +------+------+ | a | b | +------+------+ | a | a | | a | a | | a | a | +------+------+ 3 rows in set (0.00 sec)
因此,我们可以总结一下,CHAR数据类型会忽略并修剪其字符串末尾的多余空间,而VARCHAR不会-除非 在比较期间 :
mysql> select a from test where a = 'a '; +------+ | a | +------+ | a | | a | +------+ 2 rows in set (0.00 sec) mysql> select a from test where a = 'a'; +------+ | a | +------+ | a | | a | +------+ 2 rows in set (0.00 sec) mysql> select a from test where a = ' a'; +------+ | a | +------+ | a | +------+ 1 row in set (0.00 sec)
那么,对于CHAR类型也是如此吗?
mysql> select a from test where b = 'a '; +------+ | a | +------+ | a | | a | +------+ 2 rows in set (0.00 sec) mysql> select a from test where b = 'a'; +------+ | a | +------+ | a | | a | +------+ 2 rows in set (0.00 sec) mysql> select a from test where b = ' a'; +------+ | a | +------+ | a | +------+ 1 row in set (0.00 sec)
这显示 CHAR和VARCHAR类型具有不同的存储方法,但遵循相同的规则进行纯粹的字符串比较 。尾随空格将被忽略;而前导空格会修改字符串本身。