float,double容易产生误差,对精确度要求比较高时,建议使用decimal来存,decimal在mysql内存是以字符串存储的,用于定义货币要求精确度高的数据。
[例子]
新建一个tab表(定义两个字段分别为float与decimal)
代码如下 | 复制代码 |
create table tab(col_f float(10,2), col_d decimal(10,2)); 插入两行记录,做为实验 insert into tab values(1234567.21, 1234567.21),(9876543.21, 9876543.12); |
在数据迁移中,float(M,D)是非标准定义,最好不要这样使用。M为精度,D为标度。
代码如下 | 复制代码 |
mysql> create table t1(c1 float(10,2), c3 decimal(10,2)); Query OK, 0 rows affected (0.02 sec) mysql> insert into t1 values(1234567.23, 1234567.23); mysql> select * from t1; mysql> insert into t1 values(9876543.21, 9876543.12); mysql> |
不定义fload, double的精度和标度时,存储按给出的数值存储,这于OS和当前的硬件有关。
decimal默认为decimal(10,0)
因为误差问题,在程序中,少用浮点数做=比较,可以做range比较。如果数值比较,最好使用decimal类型。
精度中,符号不算在内:
代码如下 | 复制代码 |
mysql> insert into t1 values(-98765430.21, -98765430.12); Query OK, 1 row affected (0.01 sec) mysql> select * from t1; |
float占4个字节,double占8个字节,decimail(M,D)占M+2个字节。
decimal 类型可以精确地表示非常大或非常精确的小数。大至 1028(正或负)以及有效位数多达 28 位的数字可以作为 decimal类型存储而不失其精确性。该类型对于必须避免舍入错误的应用程序(如记账)很有用。
float是浮点数,不能指定小数位。
decimal是精确数,可以指定精度。
对mysql 5来说 decimal(p,s)中p最大为65,S最大为30
decimal数据类型最多可存储 38 个数字,它存储了一个准确(精确)的数字表达法,不存储值的近似值。
当数据值一定要按照指定精确存储时,可以用带有小数的decimal数据类型来存储数字。
float和real数据类型被称为近似的数据类型。不存储精确值.当要求精确的数字状态时,比如在财务应用程序中,在那些需要舍入的操作中,或在等值核对的操作中,就不使用这些数据类型。这时就要用integer、decimal、money或smallmone数据类型。
在 WHERE 子句搜索条件中(特别是 = 和 <> 运算符),应避免使用float或real列。最好限制使用float和real列做> 或 < 的比较。
float 使用的数据类型就是C语言里面的float, decimal使用的是mysql定义的decimal_t, 这个源文件decimal.c我看过, 结构体时这么定义的:
代码如下 | 复制代码 |
/** intg is the number of *decimal* digits (NOT number of decimal_digit_t's !) before the point frac is the number of decimal digits after the point len is the length of buf (length of allocated space) in decimal_digit_t's, not in bytes sign false means positive, true means negative buf is an array of decimal_digit_t's */ typedef struct st_decimal_t { int intg, frac, len; my_bool sign; decimal_digit_t buf[9]; } decimal_t; |
所以表示的数的精度和范围就知道了