赞
踩
这个问题也是比较奇怪的,明明设置的是varchar
类型,但存储的结果却是科学计数法,这还了得,必须找一下原因了
[uuid] => 1460444056320623751784
[log_time] => 2016-05-30 01:03:01
[daily_nums] => 1.125899906842624e15
就是这个daily_nums
字段,十分的奇怪。
update test set daily_nums_nums =pow(2,x) where 1 ;
此处的pow
函数是求幂次方的,博主这里是求2的n
次方。,对了,mysql
版本是5.7
$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";
这里给出的是varchar(100)
类型,没道理存不下小小十几位的数据才对,怪哉怪哉
明明是varchar
结果,为什么反而成大数了了呢,推测是两个可能
(1)数据库读出来是科学计数法
(2)数据库里面存储的就是科学计数法
答案是第二种
此处应该是由于pow()
这个函数的原因导致的,当2^50
的时候,已经达到了15
位,当51
次方的时候,超过了15
位,就记成了科学技术法
2^ 50 = 562949953421312
2^ 51 = 1.125899906842624e15
猜测也是有内部的数据结构导致的,类似于浮点型的精度问题,但是没找到具体的答案,这里不再深究。
参考php
的14
位大数转化为科学计数法:php使用位运算来实现日留存的算法
更改字段为bigint
即可,下面可以测试下,当插入科学计数法的时候,bigint
和varchar
的区别:
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
daily_nums为bigint, test_nums为varchar
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)
最终发现,当字段为bigint
的时候,是可以自动调节为数字的。只不过bigint
能存储的长度也有限,难保不会超过,所以用下一个方法
update test set daily_nums =pow(2,x) | 0
这里选择0
,这样在保证值不变的情况下,也能正常存储了,经测试无误,可以存储为大数。
end
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。