MySQL 数据类型(float)的注意事项

我就是我 2022-03-28 07:43 337阅读 0赞

摘要:
今天左哥问起一个float浮点数类型的问题,这个类型用的不多,所以也不太了解,现在打算测试下。

知识点:
float:浮点数,单精度,占4字节。

测试

  1. root@localhost : test 05:49:32>create table fl(id int,fl float);
  2. Query OK, 0 rows affected (0.05 sec)
  3. root@localhost : test 05:49:40>insert into fl values(1,123456);
  4. Query OK, 1 row affected (0.00 sec)
  5. root@localhost : test 05:49:51>insert into fl values(2,123.456);
  6. Query OK, 1 row affected (0.00 sec)
  7. root@localhost : test 05:49:57>insert into fl values(3,1234.567);#7位了
  8. Query OK, 1 row affected (0.00 sec)
  9. root@localhost : test 05:50:13>insert into fl values(4,1234567);#7位了
  10. Query OK, 1 row affected (0.00 sec)
  11. root@localhost : test 05:50:26>select * from fl;
  12. +------+-------------+
  13. | id | fl |
  14. +------+-------------+
  15. | 1 | 123456 |
  16. | 2 | 123.456 |
  17. | 3 | 1234.57 |
  18. | 4 | 1.23457e+06 |
  19. +------+-------------+
  20. 4 rows in set (0.00 sec)

从上面看出:默认的float类型都只能存6个数字(包括小数点前后的位数),整数超过6位就被科学计数表示(id=4),小数位超出则需要四舍五入。那指定float(m)的精度呢?

  1. root@localhost : test 05:59:08>create table fl(id int,fl float(20));
  2. Query OK, 0 rows affected (0.04 sec)
  3. root@localhost : test 05:59:28>show create table fl\G;
  4. *************************** 1. row ***************************
  5. Table: fl
  6. Create Table: CREATE TABLE `fl` (
  7. `id` int(11) DEFAULT NULL,
  8. `fl` float DEFAULT NULL
  9. ) ENGINE=MyISAM DEFAULT CHARSET=utf8
  10. 1 row in set (0.00 sec)
  11. root@localhost : test 05:59:35>insert into fl values(1,123456);
  12. Query OK, 1 row affected (0.00 sec)
  13. root@localhost : test 05:59:44>insert into fl values(2,123.456);
  14. Query OK, 1 row affected (0.00 sec)
  15. root@localhost : test 05:59:46>insert into fl values(3,1234.567);#7位了
  16. Query OK, 1 row affected (0.00 sec)
  17. root@localhost : test 05:59:50>insert into fl values(4,1234567);#7位了
  18. Query OK, 1 row affected (0.00 sec)
  19. root@localhost : test 05:59:53>select * from fl;
  20. +------+-------------+
  21. | id | fl |
  22. +------+-------------+
  23. | 1 | 123456 |
  24. | 2 | 123.456 |
  25. | 3 | 1234.57 |
  26. | 4 | 1.23457e+06 |
  27. +------+-------------+
  28. 4 rows in set (0.01 sec)

从上面看出:和默认的float一样。所以:默认float和float(m)一样 ,m<=24; 都是默认float类型,都只能存6个数字(包括小数点前后的位数),整数超过6位就被科学计数表示(id=4);小数位超出则需要四舍五入。那指定他的标度float(m,d) 呢?

  1. mysql> show create table fl\G;
  2. *************************** 1. row ***************************
  3. Table: fl
  4. Create Table: CREATE TABLE `fl` (
  5. `id` int(11) DEFAULT NULL,
  6. `fl` float(7,4) DEFAULT NULL
  7. ) ENGINE=MyISAM DEFAULT CHARSET=utf8
  8. 1 row in set (0.02 sec)
  9. ERROR:
  10. No query specified
  11. mysql> insert into fl values(1,123456);#整数是3位,超出了
  12. Query OK, 1 row affected, 1 warning (0.00 sec)
  13. mysql> insert into fl values(3,123.4567);
  14. Query OK, 1 row affected (0.00 sec)
  15. mysql> insert into fl values(2,123.45678);#小数位超出,四舍五入
  16. Query OK, 1 row affected (0.00 sec)
  17. mysql> insert into fl values(4,12.456789);#小数位超出,四舍五入
  18. Query OK, 1 row affected (0.00 sec)
  19. mysql> select * from fl;
  20. +------+----------+
  21. | id | fl |
  22. +------+----------+
  23. | 1 | 999.9999 |
  24. | 3 | 123.4567 |
  25. | 2 | 123.4568 |
  26. | 4 | 12.4568 |
  27. +------+----------+
  28. 4 rows in set (0.00 sec)

从上面看出:float(m,d):小数点后位数为d,即整数位数为(m-d),整数位超出则整数为(m-d)个999,小数点后位数为(d)个9999,不用科学计算了;若小数位超出,则需要四舍五入。要是float(m,d)遇到m和d一样呢?

  1. mysql> CREATE TABLE `fl` (
  2. -> `id` int(11) DEFAULT NULL,
  3. -> `fl` float(4,4) DEFAULT NULL
  4. -> ) ENGINE=MyISAM DEFAULT CHARSET=utf8;
  5. Query OK, 0 rows affected (0.04 sec)
  6. mysql> insert into fl values(1,123456);
  7. Query OK, 1 row affected, 1 warning (0.00 sec)
  8. mysql> insert into fl values(2,123.45678);
  9. Query OK, 1 row affected, 1 warning (0.00 sec)
  10. mysql> insert into fl values(3,123.4567);
  11. Query OK, 1 row affected, 1 warning (0.00 sec)
  12. mysql> insert into fl values(4,12.456789);
  13. Query OK, 1 row affected, 1 warning (0.00 sec)
  14. mysql> select * from fl;
  15. +------+--------+
  16. | id | fl |
  17. +------+--------+
  18. | 1 | 0.9999 |
  19. | 2 | 0.9999 |
  20. | 3 | 0.9999 |
  21. | 4 | 0.9999 |
  22. +------+--------+
  23. 4 rows in set (0.00 sec)

从上面看出:float(m,d):若m和d一样,则先把小数位数先满足了,再分配整数位数。所以只有小数点位数,而整数位是0。

之前提过的m<=24,要是大于24呢?

  1. mysql> CREATE TABLE `fl` (
  2. -> `id` int(11) DEFAULT NULL,
  3. -> `fl` float(25) DEFAULT NULL
  4. -> ) ENGINE=MyISAM DEFAULT CHARSET=utf8;
  5. Query OK, 0 rows affected (0.01 sec)
  6. mysql> show create table fl\G;
  7. *************************** 1. row ***************************
  8. Table: fl
  9. Create Table: CREATE TABLE `fl` (
  10. `id` int(11) DEFAULT NULL,
  11. `fl` double DEFAULT NULL
  12. ) ENGINE=MyISAM DEFAULT CHARSET=utf8
  13. 1 row in set (0.00 sec)

从上面看出:在没有标度的float中,从float转换成了double。而有标度的 float(m,d)当中,m>24呢?

  1. mysql> CREATE TABLE `fl` (
  2. -> `id` int(11) DEFAULT NULL,
  3. -> `fl` float(100,3) DEFAULT NULL
  4. -> ) ENGINE=MyISAM DEFAULT CHARSET=utf8;
  5. Query OK, 0 rows affected (0.01 sec)
  6. mysql> show create table fl\G;
  7. *************************** 1. row ***************************
  8. Table: fl
  9. Create Table: CREATE TABLE `fl` (
  10. `id` int(11) DEFAULT NULL,
  11. `fl` float(100,3) DEFAULT NULL
  12. ) ENGINE=MyISAM DEFAULT CHARSET=utf8

从上面看出:从float还是float,没有受到影响。不过设置这么大,在整数会变的不准;小数的位数还是m-d,位数不足用0填充(zerofill)。如下测试:

  1. mysql> show create table fl\G;
  2. *************************** 1. row ***************************
  3. Table: fl
  4. Create Table: CREATE TABLE `fl` (
  5. `id` int(11) DEFAULT NULL,
  6. `fl` float(100,3) DEFAULT NULL
  7. ) ENGINE=MyISAM DEFAULT CHARSET=utf8
  8. 1 row in set (0.00 sec)
  9. mysql> insert into fl values(5,777777777777777777777777777.5555);
  10. Query OK, 1 row affected (0.00 sec)
  11. mysql> select * from fl;
  12. +------+---------------------------------+
  13. | id | fl |
  14. +------+---------------------------------+
  15. | 5 | 777777744225350500000000000.000 | #不准了
  16. +------+---------------------------------+
  17. 1 row in set (0.00 sec)
  18. mysql> drop table fl;
  19. Query OK, 0 rows affected (0.00 sec)
  20. mysql> CREATE TABLE `fl` (
  21. -> `id` int(11) DEFAULT NULL,
  22. -> `fl` float(25,23) DEFAULT NULL
  23. -> ) ENGINE=MyISAM DEFAULT CHARSET=utf8;
  24. Query OK, 0 rows affected (0.02 sec)
  25. mysql> show create table fl\G;
  26. *************************** 1. row ***************************
  27. Table: fl
  28. Create Table: CREATE TABLE `fl` (
  29. `id` int(11) DEFAULT NULL,
  30. `fl` float(25,23) DEFAULT NULL
  31. ) ENGINE=MyISAM DEFAULT CHARSET=utf8
  32. 1 row in set (0.00 sec)
  33. mysql> insert into fl values(5,99.555555555555555);
  34. Query OK, 1 row affected (0.00 sec)
  35. mysql> select * from fl;
  36. +------+----------------------------+
  37. | id | fl |
  38. +------+----------------------------+
  39. | 5 | 99.55555725097656000000000 | #小数位被0填充
  40. +------+----------------------------+
  41. 1 row in set (0.00 sec)

注意:当float(m,d) 设置了标度之后,小数位一定会存在。当整数位没有被超过,需要用0填充;整数位被超过了,需要用9填充,小数位数不能大于30否则报错:

  1. mysql> CREATE TABLE `fl` (
  2. -> `id` int(11) DEFAULT NULL,
  3. -> `fl` float(5,3) DEFAULT NULL
  4. -> ) ENGINE=MyISAM DEFAULT CHARSET=utf8
  5. -> ;
  6. Query OK, 0 rows affected (0.03 sec)
  7. mysql> insert into fl values(1,123);
  8. Query OK, 1 row affected, 1 warning (0.00 sec)
  9. mysql> select * from fl;
  10. +------+--------+
  11. | id | fl |
  12. +------+--------+
  13. | 1 | 99.999 |
  14. +------+--------+
  15. 1 row in set (0.00 sec)
  16. mysql> insert into fl values(2,13);
  17. Query OK, 1 row affected (0.00 sec)
  18. mysql> insert into fl values(3,3);
  19. Query OK, 1 row affected (0.00 sec)
  20. mysql> select * from fl;
  21. +------+--------+
  22. | id | fl |
  23. +------+--------+
  24. | 1 | 99.999 | #9填充
  25. | 2 | 13.000 | #0填充
  26. | 3 | 3.000 |
  27. +------+--------+
  28. 3 rows in set (0.00 sec)
  29. mysql> CREATE TABLE `fl` (
  30. -> `id` int(11) DEFAULT NULL,
  31. -> `fl` float(102,100) DEFAULT NULL
  32. -> ) ENGINE=MyISAM DEFAULT CHARSET=utf8
  33. -> ) ENGINE=MyISAM DEFAULT CHARSET=utf8;
  34. ERROR 1425 (42000): Too big scale 100 specified for column 'fl'. Maximum is 30. #标度不能大于30,等于30可以建立
  35. mysql> CREATE TABLE `fl` (
  36. -> `id` int(11) DEFAULT NULL,
  37. -> `fl` float(52,50) DEFAULT NULL
  38. -> ) ENGINE=MyISAM DEFAULT CHARSET=utf8;
  39. ERROR 1425 (42000): Too big scale 50 specified for column 'fl'. Maximum is 30.

总结:float存在这么多潜在因素,用的时候需要注意,能避免就避免用。

发表评论

表情:
评论列表 (有 0 条评论,337人围观)

还没有评论,来说两句吧...

相关阅读

    相关 mysql注意事项

    1. 如果GROUP BY 的列没有索引,产生临时表. 2. 如果GROUP BY时,SELECT的列不止GROUP BY列一个,并且GROUP BY的列不是主键 ,