title: 有趣的mysql string和0比较返回1的问题 tags:
- mysql
- type
- String
- 0 categories: mysql date: 2017-06-25 18:18:56
6月19日出现了诡异的情况
开发环境所有的移动端用户无法登陆。
移动端通过rmi来访问,为了移动端可以访问权限内的数据,因此增加了相关的权限控制 RMI鉴权
那么对于登陆来说我们不会进行权限控制,此时要求必须传递的ClientInfo 为任意不存在的值。通常为了方便 我们传递的值为fake(赝品)
出现用户无法登陆时通过调试发现了一条奇怪的数据
pk_id username cell_phone password is_admin id_role creator modifier modifiedtime creationtime id_own_org id_employee is_del is_guide_open id_wxb_user id_wxb_station openid
0 liuliu 18767564542 96e79218965eb72c92a549dd5a330112 0 919 10545055918000106903 2017-06-19 17:05:52 2017-06-19 17:05:42 10545055918000106902 0 0
那么当执行sql如下
SELECT
*
FROM
tb_user
WHERE
pk_id = 'fake'
复制代码
可以查询得出如上的数据(注 pk_id 为bigint(20) unsigned)
pk_id为使用uuid_short产生的,因此对应java中使用String作为类型存储。
我们来查看一下mysql关于type转换的解释
我们执行如下sql
SELECT
0 = '',
0 = 'fake',
0 = NULL,
0 = 0,
0 = 1,
0 = '1',
0 = '1.66',
0 = '1.a',
0 = 'a.1',
0 = ' ',
0 = ' 啊',
1 = '',
NULL = NULL,
NULL <=> NULL,
NULL <=> 0,
NULL = 0,
0 = cast('fake' AS UNSIGNED)
复制代码
得到结果如下
0 = '' 0 = 'fake' 0 = NULL 0 = 0 0 = 1 0 = '1' 0 = '1.66' 0 = '1.a' 0 = 'a.1' 0 = ' ' 0 = ' 啊' 1 = '' NULL = NULL NULL <=> NULL NULL <=> 0 NULL = 0 0 = cast('fake' AS UNSIGNED)
1 1 1 0 0 0 0 1 1 1 0 1 0 1
复制代码
我们发现如下问题0和任意不能直接parse数字(如果数字打头可以parse)的比较均为true。换句话说我们认为所有不能parse为数字的值将会被parse为0
由于我们pk_id的类型为bigint unsigned 因此我们的参数江河数字进行比较,因此任何非数字打头 这个解释了我们在sql中为啥通过如上语句可以查询到pk_id为0 的数据。因为‘fake被parse为0‘(可以粗略的这么理解)
那么问题来了,为何数据中插入的uuid_short会变成0呢?如果出现了这样的问题那绝对是超出笔者所能理解的范围了。
查询binlog我们发现
插入的很明显是有具体的数值的。
接着检索到
很明显确实是有人更新了主键(将主键更新成了 ’ ‘导致落到数据库中直接变成了0 )===》具体的责任人(测试)不想去查了,各位更新时请注意。
问题解决。
最后复习一下
SELECT '0s' + 0 = 's','1s' + 0 = 's','0s' + 0 = 's1','s0' + 0 = 's00','s00' + 0 = 's00'
复制代码
不在sql中执行 可以给出结果么?