现存储数据量较大,数据中有很大一部分数据是带2位或3位小数浮点型的,考虑到存储空间较大的问题,先将带2位小数数据先做一个乘100,3位小数乘1000处理,然后在查询结果时,让PHP做一个相应的除100或除1000处理,想请问这样对数据精度及查询效率有什么影响没有?如果不行,采用什么样的方式存储浮点型数据最为合理?谢谢!

解决方案 »

  1.   

    ·         FLOAT[(M,D)] [UNSIGNED] [ZEROFILL]小(单精度)浮点数。允许的值是-3.402823466E+38到-1.175494351E-38、0和1.175494351E-38到3.402823466E+38。这些是理论限制,基于IEEE标准。实际的范围根据硬件或操作系统的不同可能稍微小些。M是小数纵位数,D是小数点后面的位数。如果M和D被省略,根据硬件允许的限制来保存值。单精度浮点数精确到大约7位小数位。如果指定UNSIGNED,不允许负值。使用浮点数可能会遇到意想不到的问题,因为在MySQL中的所有计算用双精度完成。参见A.5.7节,“解决与不匹配行有关的问题”。·         DOUBLE[(M,D)] [UNSIGNED] [ZEROFILL]普通大小(双精度)浮点数。允许的值是-1.7976931348623157E+308到-2.2250738585072014E-308、0和2.2250738585072014E-308到 1.7976931348623157E+308。这些是理论限制,基于IEEE标准。实际的范围根据硬件或操作系统的不同可能稍微小些。M是小数总位数,D是小数点后面的位数。如果M和D被省略,根据硬件允许的限制来保存值。双精度浮点数精确到大约15位小数位。如果指定UNSIGNED,不允许负值。·         DOUBLE PRECISION[(M,D)] [UNSIGNED] [ZEROFILL], REAL[(M,D)] [UNSIGNED] [ZEROFILL]为DOUBLE的同义词。除了:如果SQL服务器模式包括REAL_AS_FLOAT选项,REAL是FLOAT的同义词而不是DOUBLE的同义词。·         FLOAT(p) [UNSIGNED] [ZEROFILL]浮点数。p表示精度(以位数表示),但MySQL只使用该值来确定是否结果列的数据类型为FLOAT或DOUBLE。如果p为从0到24,数据类型变为没有M或D值的FLOAT。如果p为从25到53,数据类型变为没有M或D值的DOUBLE。结果列范围与本节前面描述的单精度FLOAT或双精度DOUBLE数据类型相同。FLOAT(p)语法与ODBC兼容。·         DECIMAL[(M[,D])] [UNSIGNED] [ZEROFILL]压缩的“严格”定点数。M是小数位数(精度)的总数,D是小数点(标度)后面的位数。小数点和(负数)的‘-’符号不包括在M中。如果D是0,则值没有小数点或分数部分。DECIMAL整数最大位数(M)为65。支持的十进制数的最大位数(D)是30。如果D被省略, 默认是0。如果M被省略, 默认是10。如果指定UNSIGNED,不允许负值。所有DECIMAL列的基本计算(+,-,*,/)用65位精度完成。
      

  2.   

    decimal类型占用空间较大,由于数据量较大,所以考虑先将数据乘1000变成整数,然后以整型类型存储,int型占用空间较decimal型小。
    在取结果的时候,查询得到的数据分别对应除100或1000,这样得到初始的数据,想知道这过程(对浮点型小数乘除运算)中会不会造成数据误差,并且用PHP处理查询结果时会不会产生效率低下的问题?
      

  3.   

    <高性能MYSQL>里面有一章专门讲述数据类型的。