• 记一次因数据类型不同,导致的MySql Join查询错误


    现象:

    一个主外键关联查询的场景,原本主键为”2105191446220001115“的数据,通过关联查询,查询出了”2105191446220001115“,”2105191446220001116“,”2105191446220001117“三条数据,

    一时间超出了自己的认知范围,数据库本身是不可能犯这种低级错误的,那错误一定是在我们的代码本身,经排除,是由于数据库字段类型不一致,在查询时,由于字段类型转换,数据精度损失造成的。

    背景:

    1. 数据库:MySql,版本:5.7.38,数据表主键类型为长整型(BigInt),最大长度20
    2. 程序生成一个19位的数据作为主键值
    3. 由于19位长整型数值在前端Javascript中会有精度损失,所以前后端交互时,将数值类型的主键转换为字符串,进行传递

    之前已经发现了长整型在Javascript中会存在精度损失,所以从数据库读取数据时,进行了数据转换,后台程序的做法是通过CAST函数进行转换,如下所示,

    -- 在Sql语句中,将一个整型数据,转换为字符串数据
    CAST(NumericalOrderDetail AS CHAR (20)) AS NumericalOrderDetail

    分析:

    基于以上背景,在某个查询中,出现了开头说的,查询结果与预期不一致的情况,经排除,锁定了错误原因,如下图所示,

    由于子查询中习惯性的对主键进行类型转换,而主查询中m的主键并没有进行类型转换,是长整型,有一种我无法证实的说法 Mysql中两个字段进行比较,如果类型不一致,会将类型小的字段自动转换为类型大的字段,然后进行比较,但在这个例子中,并不是将一个字段类型转换成了另一种,而是参与比对的双方都进行了转换,后来经过几次测试发现,这种情况下,前17位数据相同是可以匹配成功的,显然,最后2位数据,成了类型转换的牺牲品。

     

    结论:

    MySql中,进行join查询时,参与关联查询的字段,要保证类型的一致。

    建议:如果采用20位长整型作为主键的数据,不要在Sql中直接进行类型转换,将转换放到程序代码,或ORM中进行,实现数据库层面与代码层面的职责隔离。

    做程序多了,真是啥问题都能遇到......

  • 相关阅读:
    python数据分析之ipython
    Django之文件下载
    mongodb学习之:主从复制
    Django之高级视图与URL
    Django之request对象
    tornado安全应用之用户认证
    tornado安全应用之cookie
    tornado之异步web服务二
    【原创】Linux基础之测试域名IP端口连通性
    【原创】大数据基础之Mesos+Marathon+Docker部署nginx
  • 原文地址:https://www.cnblogs.com/flame7/p/16227581.html
Copyright © 2020-2023  润新知