实数是带有小数部分的数字。MySQL 既支持精确类型的存储 DECIMAL 类型, 也支持不精确类型存储 FLOAT 和 DOUBLE 类型。
DECIMAL 类型用于存储精确的小数,本质上 MySQL 是以字符串形式存放的。
所以 CPU 不支持对 DECIMAL 的直接计算,所以在 MySQL 中自身实现了 DECIMAL的高精度计算。相对而言,CPU 直接支持原生浮点计算,所以浮点运算明显更快。
浮点和 DECIMAL 类型都可以指定精度。对于 DECIMAL 列,可以指定小数点前后所允许的最大位数。这会影响列的空间消耗。MySQL 5.0 和更高版本将数字打包保存到一个二进制字符串中(每 4 个字节存 9 个数字)。例如,DECIMAL(18,9) 小数点两边将各存储 9 个数字,一共使用 9 个字节:小数点前的数字用 4 个字节,小数点后的数字用 4 个字节,小数点本身占 1 个字节。
MySQL 5.0 和更高版本中的 DECIMAL 类型允许最多 65 个数字。
浮点类型在存储同样范围的值时,通常比 DECIMAL 使用更少的空间。FLOAT使用 4 个字节存储,DOUBLE 占用 8 个字节,所以 DOUBLE 比 FLOAT 有更高的精度和更大的范围。
因为需要额外的空间和计算开销,所以应该尽量只在对小数进行精确计算时才使用 DECIMAL,例如存储财务或金融数据,在精度不敏感和需要快速运算的时候,选择 FLOAT 和 DOUBLE。
但在数据量比较大的而且要求精度时,可以考虑使用 BIGINT 代替 DECIMAL,将需要存储的货币单位根据小数的位数乘以相应的倍数即可。假设要存储财务数据精确到万分之一分,则可以把所有金额乘以一百万,然后将结果存储在 BIGINT里,这样可以同时避免浮点存储计算不精确和 DECIMAL 精确计算代价高的问题。