标签归档:Mysql

当一个字符串和 false 比较的时候会发生什么?

今天在写程序的时候,遇到个问题,这个问题是这样的:

我有一个表:

CREATE TABLE IF NOT EXISTS `session` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `token` varchar(32) NOT NULL,
  `profile` varchar(1000) NOT NULL,
  `created_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
  PRIMARY KEY (`id`)
) ENGINE=MyISAM  DEFAULT CHARSET=utf8 AUTO_INCREMENT=41 ;

和一些数据:

(38, '395d5feaf28df01aafe0781a7f34acbe', 'a:3:{s:2:"id";s:1:"2";s:8:"username";s:7:"wanmeng";s:12:"created_time";s:19:"2011-11-18 19:37:33";}', '2011-12-03 14:14:35'), 
(39, '0e0ca06ed9ad86937f190eb9544ac935', 'a:3:{s:2:"id";s:1:"1";s:8:"username";s:6:"delphi";s:12:"created_time";s:19:"2011-11-18 13:29:40";}', '2011-12-03 14:28:36'), 
(31, '3cba76b97cf123009632bdaa5a306385', 'a:3:{s:2:"id";s:1:"1";s:8:"username";s:6:"delphi";s:12:"created_time";s:19:"2011-11-18 13:29:40";}', '2011-12-02 15:50:21'), 
(30, 'fa356333dd3ee8f1b18b8bf0a827e34c', 'a:3:{s:2:"id";s:1:"1";s:8:"username";s:6:"delphi";s:12:"created_time";s:19:"2011-11-18 13:29:40";}', '2011-12-01 15:32:47')

在我执行  SELECT * FROM session WHERE token = false 的时候,我本以为没有记录会返回,但是mysql却给我返回了2条记录:

39  0e0ca06ed9ad86937f190eb9544ac935    a:3:{s:2:"id";s:1:"1";s:8:"username";s:6:"delphi";...   2011-12-03 22:28:36 
30  fa356333dd3ee8f1b18b8bf0a827e34c    a:3:{s:2:"id";s:1:"1";s:8:"username";s:6:"delphi";...   2011-12-01 23:32:47

我猜到了问题应该是出在数据类型转换上,于是我就修改了查询语句,让字符串和null值作比较而不是false,但为什么会这样却一时半会儿没想明白,于是就在stackoverflow上提了个问题 ,结果当然是被人家当小白教育了一翻……但原因我算是知道了。

在Mysql中是没有boolean这种数据类型的,boolean在Mysql中实际上是用Tinyint表示的,0代表false,1代表true。

所以上边那个查询实际上就是相当于

SELECT * FROM session WHERE token = 0

当一个字符串和Tinyinit作比较的时候,Mysql会先将字符串转换为数字类型,数字开头的字符串取前边的可以转换的数字字符转为数字,如果字符串是字母开头的,则直接转为数字0

于是那些以字母开头和数字0开头的记录便被取出来了。