当前位置:   article > 正文

mysql存储数据,varchar类型中的数据变成了科学计数法?_数据库使用varchar存储,但是通过mybatis读出来的数据成了科学计数法,怎么解决

数据库使用varchar存储,但是通过mybatis读出来的数据成了科学计数法,怎么解决

一、前言

      这个问题也是比较奇怪的,明明设置的是varchar类型,但存储的结果却是科学计数法,这还了得,必须找一下原因了

1、表现形式

            [uuid] => 1460444056320623751784
            [log_time] => 2016-05-30 01:03:01
            [daily_nums] => 1.125899906842624e15
  • 1
  • 2
  • 3

      就是这个daily_nums字段,十分的奇怪。

2、出现错误的sql

update test set daily_nums_nums =pow(2,x) where 1
  • 1

      此处的pow函数是求幂次方的,博主这里是求2的n次方。,对了,mysql版本是5.7

二、问题排查

1、数据表结构

       $sql = "CREATE TEMPORARY TABLE if not exists test (
            uuid varchar(32) NOT NULL PRIMARY KEY,
            `log_time` datetime NOT NULL ,
            `daily_nums` VARCHAR(100) NOT NULL DEFAULT '0',
            UNIQUE KEY `uuid` (`uuid`),
            KEY (log_time)
        ) DEFAULT CHARSET utf8 COLLATE utf8_general_ci";
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

      这里给出的是varchar(100)类型,没道理存不下小小十几位的数据才对,怪哉怪哉

2、错误推测

明明是varchar结果,为什么反而成大数了了呢,推测是两个可能

(1)数据库读出来是科学计数法
(2)数据库里面存储的就是科学计数法
  • 1
  • 2

答案是第二种

3、最终原因

      此处应该是由于pow()这个函数的原因导致的,当2^50的时候,已经达到了15位,当51次方的时候,超过了15位,就记成了科学技术法

	2^ 50  = 562949953421312
	2^ 51 =  1.125899906842624e15
  • 1
  • 2

      猜测也是有内部的数据结构导致的,类似于浮点型的精度问题,但是没找到具体的答案,这里不再深究。

      参考php14位大数转化为科学计数法:php使用位运算来实现日留存的算法

三、解决方案

1、更改数据结构

更改字段为bigint即可,下面可以测试下,当插入科学计数法的时候,bigintvarchar的区别:

(1)表结构
		CREATE TABLE `temp_drr_test` (
  `uuid` varchar(32) NOT NULL,
  `daily_nums` bigint(20) NOT NULL DEFAULT '0',
  `weekly_nums` bigint(20) NOT NULL DEFAULT '0',
  `monthly_nums` bigint(20) NOT NULL DEFAULT '0',
  `test_nums` varchar(100) DEFAULT '',
  UNIQUE KEY `uuid` (`uuid`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
daily_nums为bigint, test_nums为varchar
  • 1
(2)分别更新两个字段为 科学计数法 :2.251799813685248e15
	mysql> select * from temp_drr_test;
+------+---------------------+---------------------+--------------+---------------------+
| uuid | daily_nums          | weekly_nums         | monthly_nums | test_nums           |
+------+---------------------+---------------------+--------------+---------------------+
| 1111 | 4611686018427387904 | 9223372036854775807 |            0 | 4611686018427387904 |
+------+---------------------+---------------------+--------------+---------------------+
1 row in set (0.00 sec)

mysql> update temp_drr_test set daily_nums=2.251799813685248e15;
Query OK, 1 row affected (0.00 sec)
Rows matched: 1  Changed: 1  Warnings: 0

mysql> select * from temp_drr_test;
+------+------------------+---------------------+--------------+---------------------+
| uuid | daily_nums       | weekly_nums         | monthly_nums | test_nums           |
+------+------------------+---------------------+--------------+---------------------+
| 1111 | 2251799813685248 | 9223372036854775807 |            0 | 4611686018427387904 |
+------+------------------+---------------------+--------------+---------------------+
1 row in set (0.00 sec)

mysql> update temp_drr_test set test_nums=2.251799813685248e15;
Query OK, 1 row affected (0.00 sec)
Rows matched: 1  Changed: 1  Warnings: 0

mysql> select * from temp_drr_test;
+------+------------------+---------------------+--------------+----------------------+
| uuid | daily_nums       | weekly_nums         | monthly_nums | test_nums            |
+------+------------------+---------------------+--------------+----------------------+
| 1111 | 2251799813685248 | 9223372036854775807 |            0 | 2.251799813685248e15 |
+------+------------------+---------------------+--------------+----------------------+
1 row in set (0.00 sec)
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31

      最终发现,当字段为bigint的时候,是可以自动调节为数字的。只不过bigint能存储的长度也有限,难保不会超过,所以用下一个方法

2、按位或上一个值

update test set daily_nums =pow(2,x) | 0 
  • 1

      这里选择0,这样在保证值不变的情况下,也能正常存储了,经测试无误,可以存储为大数。

end

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/小小林熬夜学编程/article/detail/688301
推荐阅读
相关标签
  

闽ICP备14008679号