MYSQL中浮点类型的区别

  张一帆   2017年05月23日


mysql

  除了《MYSQL中tinyint(1)的正确理解》所述的整形以外,mysql还有两种小数类型,一种是定点数类型(decimal,numeric),一种是浮点数类型(float,double)。

  我们先来说说定点数,他存的值一定是准确的。所以说这个类型通常是用来做需要保存准确度的数值类型的,比如金额类型的数据。numeric其实是被decimal实现的,所以说在意义上来将,numeric和decimal是同一个道理。

  decimal(M,N),其中M代表位数的总和,N代表小数点的位数,不足则补零,超出的则用四舍五入的方式进位到小数点N位,举个例子:

decimal(5,3)。

 该字段可以存储decimal类型的字段,字符总数为5位,小数点3位。也就是说这个字段可以存储任何5个数字以及3个小数,所以存储范围是-99.999~99.999。通过测试,我们可以总结一下几个规律:

输入 结果
0 0.000
111.111 out of range value
11111 out of range value
1.1112 1.111
1.1115 1.112
9.9998 10.000
99.9998 out of range value

  让我们来关注下如果没有设置小数点位数的时候,decimal会是什么样子。比如,我设置decimal(5),它其实就跟decimal(5,0)是等价的。也就是说这种情况下是没有小数的,如果你非要添加小数的话,他最终还是会按照四舍五入的方法进位至个位的最后存入数据库。

  如果你在设置decimal的时候不给他设置M值,那么mysql会默认给他赋成decimal(10)的。

  那么decimal最大的长度能够设置成多长呢?

The maximum number of digits for DECIMAL is 65, but the actual range for a given DECIMAL column can be constrained by the precision or scale for a given column. When such a column is assigned a value with more digits following the decimal point than are permitted by the specified scale, the value is converted to that scale. (The precise behavior is operating system-specific, but generally the effect is truncation to the permissible number of digits.)
  DECIMAL 最大的数字长度是65位,但是实际的范围受制于给定的decimal列存储的precision(指M)和scale(指N)。当给此列被赋上一个由整数和不符合规范长度的小数组成的数时,这个值会被转化成符合规范的scale。(precise是操作系统指定的,但普遍来说效果是将截断至允许范围。)

  如果你设置decimal的长度大于65的时候,mysql会报“Too-big precision 66 specified for ‘f’ maximun is 65.”的错误。如果你去设置值时,跟上边举得例子是一摸一样的。

输入 结果
11111111111111111111111111111111111111111111111111111111111111111(65个1) out of range value
111111111111111111111111111111111111111111111111111111111111.1111(64个1) 111111111111111111111111111111111111111111111111111111111111.11110
11111111111111111111111111111111111111111111111111111111111111.1111(66个1) out of range value

  接下来让我们再看看浮点数类型,他们存储的都是一个近似值。mysql用4字节存储单精度值(float),用8字节存储双精度值(double)。由于单精度和双精度牵涉的只是有些多,在这里我先埋个坑,等自己真正明白了再给补上吧。

  mysql允许一种非标准的语法来定义float(M,D) 或者 real(M,D)或者double precision(M,D)。在这里,M代表所存储的字符长度以及D位的小数部分。举个例子,一列定义成float(7,4),那么可以存储形如-999.9999,mysql会在超出这个范围存储时对这个值进行四舍五入的操作,所以你在插入999.00009的时候,系统会给算个近似值等于999.0001。

  由于浮点数类型的值是近似数而不是一个确切的数值,所以想用他们来存储确切值时会出现意想不到的错误。所以,我们还是尽量避免使用这种类型的值吧。