美文网首页
mysql字符串与数字比较问题

mysql字符串与数字比较问题

作者: 二当家的黑板报 | 来源:发表于2019-09-14 11:29 被阅读0次

由于某些原因,项目中使用到雪花id(固定18位的数字)作为mysql表的PRIMARY KEY,且id类型为varchar。

使用id做偏移量分页时,踩到了一些类型的坑,如下:

mysql> select '465543153571602432' <= 465543153571602431;
+-------------------------------------------+
| '465543153571602432' = 465543153571602431 |
+-------------------------------------------+
|                                         1 |
+-------------------------------------------+

如果程序中传入的id是long类型的话,这样是相同的,原因是mysql会将字符串自动转换为数字类型,但是精度丢失导致了'465543153571602432' 等于 465543153571602431。

正确的应该是传入字符串类型:

mysql> select '465543153571602432' <= '465543153571602431';
+----------------------------------------------+
| '465543153571602432' <= '465543153571602431' |
+----------------------------------------------+
|                                            0 |
+----------------------------------------------+

如果传入的参数都是雪花id,那么上面的方案应该就可以解决问题了,但是如果传入的是5,就会存在下面的问题:

mysql> select '465543153571602432' <= '5';
+-----------------------------+
| '465543153571602432' <= '5' |
+-----------------------------+
|                           1 |
+-----------------------------+

mysql字符串比较时,不管你的字符串长度的,按字符顺序比较下去,第一个相同,就比较第二个等,所以这就不符合我的需求了。

所以需要将字符类型转换为数字类型来比较:

mysql> select CONVERT('465543153571602432',SIGNED) <= 5;
+-------------------------------------------+
| CONVERT('465543153571602432',SIGNED) <= 5 |
+-------------------------------------------+
|                                         0 |
+-------------------------------------------+

那么是不是第二种方案也可以满足第一种方案的情况:

mysql> select CONVERT('465543153571602432',SIGNED) <= 465543153571602431;
+------------------------------------------------------------+
| CONVERT('465543153571602432',SIGNED) <= 465543153571602431 |
+------------------------------------------------------------+
|                                                          0 |
+------------------------------------------------------------+

答案是可以满足,但是性能不允许,因为第二种方案走不了索引。这个id的字段是varchar,建立的是字符串索引,转化为数字比较,是走不了字符串索引的。

所以需要做一下折中,如果是雪花id,则走第一种方案,否则走第二种方案:

        /**
     * @param offset
     * @return left是key,right是value
     */
    private ImmutablePair<String, Object> fixIdSql(String offset) {

        //判断是否雪花id
        if (StringUtils.length(offset) == 18) {
            return ImmutablePair.of("id", offset);
        } else {
            return ImmutablePair.of("CONVERT(id,SIGNED)", Long.parseLong(offset));
        }
    }

这样就满足大部分雪花id查询的性能,也能处理一些偶尔非雪花id的需求。

更多技术文章请查看原文

相关文章

  • mysql字符串与数字比较问题

    由于某些原因,项目中使用到雪花id(固定18位的数字)作为mysql表的PRIMARY KEY,且id类型为var...

  • linux shell中的比较符号与特殊符号介绍

    shell字符串比较、判断是否为数字 二元比较操作符,比较变量或者比较数字。注意数字与字符串的区别。 整数比较 -...

  • MySQL字符串和数字比较

    在项目中,我们经常会用到模糊搜索,但如果错误的将字符串类型和数字类型做比较,有时搜索出来的结果就并不是我们预期的。...

  • 2018-10-25

    字符串与数字: 数字与数字 字符串与boolean(真假类型) 字符串与字符串 数字与boolean(真假类型)

  • JavaScript == 相等运算符自动转换的4种简单情形

    情景1:比较数字和字符串 比较数字和字符串时,都要将字符串转换为数据,再两个数字进行比较 比如无法转换为数字,是字...

  • Java 字符串_1

    数字与字符串相转换 平时开发的时候经常会遇到需要将字符串转成数字或者数字转换成字符串的情况,这个知识点比较简单,所...

  • mysql 语句中数字与字符串比较的情况

    一、 问题原因同事项目出现Bug,让我看看,项目在运行过程中一直出现同一条数据,而将sql在数据库执行是正常的,没...

  • PHP数字与字符串比较

    2018-09-18参考文献:Darry_Zhao: PHP数字与字符串比较的误区 今天工作中发现提供的订单查询接...

  • mysql之字符串进行运算或大小比较

    mysql字符串进行加减乘除的运算: 在mysql当中,字符串类型间进行加减乘除运算的时候,会截取字符串以数字开头...

  • 关于JavaScript的隐式转换

    一、 数字与数字之间的转换 1.字符串加数字,数字就会转成字符串。 2.数字减字符串,字符串转成数字。如果字符串不...

网友评论

      本文标题:mysql字符串与数字比较问题

      本文链接:https://www.haomeiwen.com/subject/amaoyctx.html