【问题标题】:Sould I store price as decimal or Integer in Mysql?我应该在 Mysql 中将价格存储为十进制还是整数?
【发布时间】:2016-09-03 13:52:15
【问题描述】:

我目前正在使用decimal 来存储价格数据(将 4.2 美元存储为 4.20),但比较相等性似乎有些困难,即需要计算两个数字之间的差异(abs(number1 - number 2) < 0.01)而不是使用 @ 987654323@

所以我想知道将价格存储为整数是否会更好,例如将 $4.2 存储为 420。

谢谢。

【问题讨论】:

  • 我认为 MySQL 比较十进制数没有问题。这可能发生在您的编程语言中,并且只有当您将它们转换为浮点时。不要那样做。如果您没有可用的 BigDecimal 之类的东西,请考虑使用select price*100 来避免这种情况。

标签: mysql integer decimal


【解决方案1】:

来自MySQL 5.7 Reference Manual

查看精确值和近似值处理差异的另一种方法是将一个小数多次添加到总和中。考虑以下存储过程,它将 .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 中存储的量为FLOATDOUBLE,就会有这个问题,但这只是DECIMAL

当使用DECIMAL 时,您可以使用数据库中的常用比较。 MySQL 不会返回错误结果。

但是当您从数据库中获取数据并将它们分配给编程语言中的变量时要小心。尤其是在动态类型变量的编程语言中......

然后您应该检索乘以 10 的值并对 integerlong integer 进行操作...或者更好地使用特殊库对带逗号的数字进行财务操作...

【讨论】:

    【解决方案2】:

    DECIMAL(8,2) 将准确存储 4.20。比较等没有问题。(8,2) 为您提供高达一百万美元的价值;根据需要进行调整。

    【讨论】:

    • mySQL小数与python小数比较时会出现问题,即从mySQL中提取数据并在python中比较相等性。
    【解决方案3】:

    您可以使用所谓的次要货币。基本上是将 4.20 美元存储为 420。这是与支付处理网关或 api 通信时通常采用的做法。

    好处是数据库和存储中的所有算术运算都使用整数而不是小数进行。这意味着它们占用的空间更少,操作更快。

    正如@thilo 所指出的,您还可以避免有时会潜入的浮点错误。

    显示时,只需除以 100

    【讨论】:

    • 最重要的是,它避免了在根本没有适当的十进制处理的环境中出现浮点数的问题(即舍入错误)。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-08-05
    • 2013-06-27
    • 1970-01-01
    • 1970-01-01
    • 2010-12-15
    • 2012-07-05
    相关资源
    最近更新 更多