我目前正在使用decimal
存储价格数据(将4.2美元存储为4.20),但似乎难以比较相等,即需要计算2个数字之间的差异(abs(number1 - number 2) < 0.01
)而不是使用number1 == number2
所以我想知道将价格存储为整数会更好,比如将商店4.2美元定为420。
感谢。
答案 0 :(得分:10)
您可以使用所谓的次要货币。这基本上将4.20美元存储为420.这种做法通常在与支付处理网关或API进行通信时进行调整。
好处是数据库和存储中的所有算术运算都使用整数而不是小数。这意味着它们占用的空间更少,操作更快。
正如@thilo所指出的那样,你也避免了有时可能会出现的浮点错误。
在显示时,只需除以100
答案 1 :(得分:4)
另一种查看精确值和近似值处理差异的方法是多次向总和中添加一个小数字。请考虑以下存储过程,它将.0001添加到变量1,000次。
CREATE PROCEDURE p () BEGIN DECLARE i INT DEFAULT 0; DECLARE d DECIMAL(10,4) DEFAULT 0; DECLARE f FLOAT DEFAULT 0; WHILE i < 10000 DO SET d = d + .0001; SET f = f + .0001E0; SET i = i + 1; END WHILE; SELECT d, f; END;
d和f的总和逻辑上应该是1,但这仅适用于小数计算。浮点计算引入了小错误:
+--------+------------------+ | d | f | +--------+------------------+ | 1.0000 | 0.99999999999991 | +--------+------------------+
因此,在处理浮点类型时,您所编写的问题始终存在。实际上,如果MySQL中存储的数量为FLOAT
或DOUBLE
,则会出现此问题,但这只是DECIMAL
。
使用DECIMAL
时,您可以使用数据库中的常规比较。 MySQL确实没有返回错误的结果。
但是从数据库中获取数据并将其分配给编程语言中的变量时要小心。特别是在编程语言中,它是变量的动态类型......
然后您应该检索该值乘以100并对integer
或long integer
进行操作...或者更好地使用特殊库对带有逗号的数字进行财务操作...
答案 2 :(得分:2)
DECIMAL(8,2)
将完全存储4.20。比较等没有问题(8,2)
给你价值高达一百万美元;根据需要调整。