用于在MySQL数据库中存储货币值的最佳数据类型

Bri*_*her 208 mysql sql sqldatatypes

货币值的最佳SQL数据类型是什么?我正在使用MySQL,但更喜欢数据库独立类型.

Kib*_*bee 224

喜欢的东西Decimal(19,4)通常工作得很好,在大多数情况下.您可以调整比例和精度,以满足您需要存储的数字的需要.即使在SQL Server中,我倾向于不使用" money",因为它是非标准的.

  • 关于大小的一点:根据MSDN(http://msdn.microsoft.com/en-us/library/ms187746.aspx),十进制(10,4)和十进制(19,4)都使用9个字节的存储空间,所以不妨为额外的9位数量的弹簧. (52认同)
  • 使用`(19,4)`代替`(19,2)`有什么好处? (5认同)
  • 我的好处是......我需要我所有的表格行等于特定数量的钱。假设金额为 10.00 美元。随着新行的添加,每一行的数量都会发生变化。如果表中有 3 行。10 / 3 = 3.3333333333...但只有两位小数,它们被存储为 3.33。所以当你把它们加起来时,3.33 + 3.33 + 3.33 = 9.99。我们损失了一分钱!在更大的数据集上变得更糟。存储在 19,4 并求和您的总数,然后将输出四舍五入为 19,2.. (2认同)

Sea*_*nJA 48

您唯一需要注意的是,如果您从一个数据库迁移到另一个数据库,您可能会发现DECIMAL(19,4)和DECIMAL(19,4)意味着不同的东西

(http://dev.mysql.com/doc/refman/5.1/en/precision-math-decimal-changes.html)

    DBASE: 10,5 (10 integer, 5 decimal)
    MYSQL: 15,5 (15 digits, 10 integer (15-5), 5 decimal)


Sco*_*son 17

阿萨夫的回应

取决于你得到多少钱......

听起来很轻浮,但实际上它是相关的.

直到今天我们还有一个问题,即记录未能插入到我们的费率表中,因为其中一列(GrossRate)设置为十进制(11,4),而我们的产品部门刚刚在一些令人惊叹的度假村获得了房间合同在波拉波拉岛,每晚出售数百万太平洋法郎......这在10年前设计数据库架构时从未被反对过.

  • 这就是我推荐小数(19,4)的原因.可能听起来有点矫枉过正,但你永远不知道什么时候你需要在那个领域存储大量的东西. (2认同)
  • @Kibbee:直到今天我都不同意你的要求.(6年(11,4)非常好......) (2认同)

Lea*_*eah 17

计算出计算所需的小数位数也很重要.

我参与了股票价格申请,要求计算一百万股的价格.报价的股价必须存储到7位精度.

  • 这是一个好点 - 特别是在金融应用程序中,"价格"肯定并不意味着"钱" (7认同)

dan*_*neb 11

对于会计应用程序,将值存储为整数是非常常见的(有些甚至可以说它是唯一的方法).要了解一下,请考虑交易金额(假设为100.23美元)和100,1000,10000等倍数,以获得所需的准确性.因此,如果您只需要存储美分并且可以安全地向上或向下舍入,则只需乘以100.在我的示例中,这将使10023成为要存储的整数.您将节省数据库中的空间,并且比较两个整数比比较两个浮点数容易得多.我的0.02美元.

  • 这怎么会比'DECIMAL`更好?在适当的时候,你需要非常小心地将便士,磨坊或者毫克翻译成美元. (2认同)

Dam*_*ian 9

超级晚进入,但GAAP是一个很好的经验法则..

如果您的申请需要处理高达万亿的货币价值,那么这应该有效:13,2如果您需要遵守GAAP(公认会计原则),那么使用:13,4

通常,在将输出舍入到13,2之前,您应该将您的货币值加总为13,4.

来源:在MySQL中存储货币价值的最佳数据类型


小智 6

这取决于数据的性质。你需要事先考虑清楚。

我的情况

  • 十进制(13,4)无符号记录货币交易
    • 存储效率高(无论如何小数点的每一侧都是 4 个字节)1
    • 符合公认会计准则
  • 十进制(19,4)无符号聚合
    • 我们需要更多空间来处理数十亿笔交易
    • 半遵守 MS Currency 数据类型不会伤害2
    • 每条记录将占用更多空间(11 字节 - 左 7 和右 4),但这很好,因为聚合1的记录较少
  • 汇率的十进制(10,5)
    • 它们通常用 5 位数字引用,因此您可以找到 1.2345 和 12.345 之类的值,但不能找到 12345.67890
    • 这是普遍的惯例,但不是编纂的标准(至少就我的快速搜索知识而言)
    • 您可以使用相同的存储将其设为十进制 (18,9),但数据类型限制是有价值的内置验证机制

为什么是 (M,4)?

  • 有些货币可以分成一千便士
  • 有货币等价物,如“Unidad de Fermento”、“CLF”,用 4 个有效小数位表示3 , 4
  • 符合美国通用会计准则

权衡

  • 较低的精度:
    • 更少的存储成本
    • 更快的计算
    • 降低计算错误风险
    • 更快的备份和恢复
  • 更高的精度:
    • 未来的兼容性(数字趋于增长)
    • 节省开发时间(当满足限制时,您不必重建半个系统)
    • 降低因存储精度不足而导致生产失败的风险

兼容至尊

尽管 MySQL 允许您使用小数 (65,30),但如果我们想要让传输选项保持打开状态,那么 31 表示比例和 30 表示精度似乎是我们的限制。

最常见的 RDBMS 中的最大规模和精度:

            精密秤
甲骨文 31 31
T-SQL 38 38
MySQL 65 30
PostgreSQL 131072 16383

6 , 7 , 8 , 9

合理极限

  1. 为什么是 (27,4)?
    • 你永远不知道系统何时需要存储津巴布韦元

2015 年 9 月津巴布韦政府表示将以 1 美元兑 35 万亿津巴布韦元的汇率将津巴布韦元兑换成美元5

我们倾向于说“是的,当然......我不需要那些疯狂的数字”。嗯,津巴布韦人也常这么说。不久前。

假设您需要以津巴布韦元记录一笔 100 万美元的交易(今天可能不太可能,但谁知道 10 年后会是什么样子?)。

  1. (100 万美元) * (35 Quadrylion ZWL) = ( 10^6 ) * (35 * 10^15) = 35 * 10^21
  2. 我们需要:
    • 2 位数字来存储“35”
    • 21 位数字来存储零
    • 小数点右边4位
  3. 这使得 decimal(27,4) 为每个条目花费我们 15 个字节
  4. 我们可以免费在左边再增加一位数字 - 我们有十进制(28,4)为 15 个字节
  5. 现在我们可以存储以津巴布韦元表示的 1000 万美元交易,或者避免再次发生恶性通货膨胀,这希望不会发生


Joh*_*ers 5

您可以使用DECIMAL(19,2)默认情况下的所有货币值,但如果您只存储低于1,000美元的值,那么这将浪费宝贵的数据库空间.

对于大多数实现来说,DECIMAL(N,2)就足够了,其中值N至少是.您希望存储在该字段中的最大总和之前的位数+ 5.因此,如果您不希望存储任何大于999999.99的值,那么DECIMAL(11,2)应该绰绰有余(直到期望发生变化).

如果您希望符合GAAP标准,那么您可以使用DECIMAL(N,4),其值N至少是.您希望存储在该字段中的最大金额之前的位数+ 7.