有趣的mysql string和0比较返回1的问题


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转换的解释

dev.mysql.com/doc/refman/…

我们执行如下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中执行 可以给出结果么?

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值