int类型存小数 mysql_mysql中慎用float数据类型

今天有同学反映,从idb查出来的数据,是以科学计数方式显示的,所以在此需要确认下是idb显示的问题,还是db存储的问题,如果是db存储的时候就是float类型(科学计数),那么可能存在数据不准确的问题,建议用int或者bigint的方式存储,在计算的时候再做相应的转化。如果,数据的范围能确认,那么使用DECIMAL(NUMERIC)也可以。

以下看下float,numeric类型的使用及需要注意的问题:

测试表:

Create Table: CREATE TABLE `test_float` (

`id` int(11) NOT NULL DEFAULT '0',

`col` float DEFAULT NULL,

`col2` decimal(5,2) DEFAULT NULL,

`col3` decimal(10,2) DEFAULT NULL,

`col4` decimal(20,2) DEFAULT NULL,

PRIMARY KEY (`id`)

) ENGINE=InnoDB DEFAULT CHARSET=gbk

测试1:

插入非越界的数据,

-- float除去小数点加在一起最多6位;

-- decimal(m,n),除去小数点,加在一起最多m位,n代表小数点后的位数;

root@test 04:17:44>insert into test_float values(1,1234.56,123.45,12345678.90,1234567890123456.78);

Query OK, 1 row affected (0.00 sec)

root@test 04:19:01>select * from test_float;

+----+---------+--------+-------------+---------------------+

| id | col     | col2   | col3        | col4                |

+----+---------+--------+-------------+---------------------+

|  1 | 1234.56 | 123.45 | 12345678.90 | 1234567890123456.78 |

+----+---------+--------+-------------+---------------------+

1 row in set (0.00 sec)

测试2:

插入越界的数据:

-- float,插入超过6位的数据;

-- decimal(m,n),插入超过m位,和超过n位的数据;

root@test 04:30:57>insert into test_float values(2,123456.123456,123123.45,12345678.123456,1234567890123456.78);

Query OK, 1 row affected, 2 warnings (0.00 sec)

root@test 04:31:11>show warnings;

+---------+------+-----------------------------------------------+

| Level   | Code | Message                                       |

+---------+------+-----------------------------------------------+

| Warning | 1264 | Out of range value for column 'col2' at row 1 |

| Note    | 1265 | Data truncated for column 'col3' at row 1     |

+---------+------+-----------------------------------------------+

2 rows in set (0.00 sec)

root@test 04:31:15>select * from test_float;

+----+---------+--------+-------------+---------------------+

| id | col     | col2   | col3        | col4                |

+----+---------+--------+-------------+---------------------+

|  1 | 1234.56 | 123.45 | 12345678.90 | 1234567890123456.78 |

|  2 |  123456 | 999.99 | 12345678.12 | 1234567890123456.78 |

+----+---------+--------+-------------+---------------------+

3 rows in set (0.00 sec)

结论:

1. float 默认只保存6位(除去小数点),如果超过6位,则四舍五入,所以float存储的数据是不精确的,只是近似值;

2. decimal,如果输入的数据超过了定义的最大值,那么则溢出,数据库里面存储的是定义的最大值,例如,decimal(5,2)输入123123.45,实际存储为999.99;

3. decimal,如果只是小数部分超过定义的长度,那么则截断(非四舍五入)指定长度,例如,decimal(10,2)输入12345678.123456,实际存储为12345678.12;

4. decimal,整数部分和小数部分是分开存储的,每9个数字占用4个字节,在mysql内部使用的二进制存储,基本没有长度的限制;

建议:

1. 尽量不用float类型;

2. 存钱之类的数据,使用int(bigint)来存,在计算的时候除以100;

3. 一定要存小数的话,decimal是不错的选择,但是需要考虑到数据的范围问题,以防越界产生的错误;

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值