我想在 MySQL 数据库中存储许多记录。它们都包含货币价值。但我不知道每个人要插入多少位。为此,我必须使用哪种数据类型? VARCHAR 或 INT(或其他数字数据类型)?
deimal(10,2)
是我使用的...您可以根据预期大小调整值
由于金钱需要精确的表示,因此不要使用像 float
这样的近似数据类型。您可以使用定点数字数据类型,例如
decimal(15,2)
15 是精度(值的总长度,包括小数位)
2 是小数点后的位数
当保持精确的精度很重要时使用这些类型,例如货币数据。
您可以使用 DECIMAL
或 NUMERIC
两者都相同
DECIMAL 和 NUMERIC 类型存储精确的数字数据值。当保持精确的精度很重要时使用这些类型,例如货币数据。在 MySQL 中,NUMERIC 被实现为 DECIMAL,因此以下关于 DECIMAL 的注释同样适用于 NUMERIC。 : MySQL
即 DECIMAL(10,2)
我更喜欢使用 BIGINT
,并将值存储在 乘以 100,这样它就会变成整数。
例如,要表示93.49
的货币值,该值应存储为9349
,同时显示该值我们可以除以100并显示。这将占用更少的存储空间。
注意:大多数情况下我们不执行货币*货币乘法,以防万一我们这样做,然后将结果除以 100 并存储,以便它返回到正确的精度。
DECIMAL
有什么优势?您创造了将便士转换为美元的需求,如果您在某个时候忘记了它,您会感到很痛苦。
$0.005
或 $0.12345
),请小心使用除垢方法,因为它们在乘以 100 后不会减少为整数。如果您知道精度在这些值中,很明显最好的选择是使用 DECIMAL
。但是,如果您不知道精度(如我的示例中所示),那么……FLOAT
是否合适?
这取决于您的需要。
通常使用 DECIMAL(10,2)
就足够了,但如果您需要更精确的值,您可以设置 DECIMAL(10,4)
。
如果您使用较大的值,请将 10
替换为 19
。
如果您的应用程序需要处理高达一万亿的货币价值,那么这应该可以:13,2 如果您需要遵守 GAAP(公认会计原则),请使用:13,4
通常,在将输出四舍五入为 13.2 之前,您应该将您的货币价值加总为 13.4。
在被问到这个问题的时候,没有人考虑过比特币的价格。在 BTC 的情况下,使用 DECIMAL(15,2)
可能是不够的。如果比特币将升至 100,000 美元或更多,我们将至少需要 DECIMAL(18,9)
来支持我们的应用程序中的加密货币。
DECIMAL(18,9)
在 MySQL (4 bytes per 9 digits) 中占用 12 个字节的空间。
我们使用双。
*喘气*
为什么?
因为它可以表示任何 15 位数字,而对小数点的位置没有限制。全部只有区区 8 个字节!
所以它可以表示:
0.123456789012345
123456789012345.0
...以及介于两者之间的任何东西。
这很有用,因为我们正在处理全球货币,并且 double
可以存储我们可能会遇到的各种小数位数。
单个 double
字段可以表示 999,999,999,999,999 日元,9,999,999,999,999.99 美元,甚至 9,999,999.99999999 比特币
如果您尝试对 decimal
执行相同操作,则需要花费 14 个字节的 decimal(30, 15)
。
注意事项
当然,使用 double
并非没有注意事项。
然而,这并不是某些人倾向于指出的准确性损失。尽管 double
本身可能在内部不精确到以 10 为底的系统,但我们可以通过 将我们从数据库中提取的值 精确到它的有效小数位来使其精确.如果需要的话。 (例如,如果要输出,则需要以 10 为基数的表示。)
需要注意的是,任何时候我们使用它进行算术运算时,我们都需要在之前对结果进行规范化(通过将其四舍五入到有效的小数位):
对其进行比较。将其写回数据库。
另一种警告是,与 decimal(m, d)
不同,其中数据库将阻止程序插入多于 m
位的数字,double
不存在此类验证。一个程序可以插入一个用户输入的 20 位数的值,它最终会被默默地记录为一个不准确的数字。
1.410000000000
(小数点后 12 位有效),但将其乘以 1,000,000,000,000(小数点后 13 位有效数字)意味着我们是使用至少 25 位有效数字。这远远超过了双倍可用的 15 个,所以在设计方面我认为它会很糟糕。
如果需要 GAAP 合规性或您需要 4 个小数位:
DECIMAL(13, 4) 支持最大值:
999,999,999.9999 美元
否则,如果 2 位小数就足够了:DECIMAL(13,2)
来源:https://rietta.com/blog/best-data-types-for-currencymoney-in/
实际上,这取决于程序员的偏好。我个人使用:numeric(15,4)
以符合公认会计原则 (GAAP)。
尝试使用
Decimal(19,4)
这通常也适用于所有其他数据库
在所有“正常”情况下,将钱存储为 BIGINT
乘以 100 或更多以使用更少的存储空间是没有意义的。
为了与 GAAP 保持一致,以 DECIMAL(13,4) 存储货币就足够了
MySQL手册读取它需要每9位4字节来存储DECIMAL。 https://dev.mysql.com/doc/refman/8.0/en/precision-math-decimal-characteristics.html
https://dev.mysql.com/doc/refman/8.0/en/precision-math-decimal-characteristics.html
DECIMAL(13,4) 表示 9 个数字 + 4 个小数位(小数位)=> 4 + 2 个字节 = 6 个字节
与存储 BIGINT 所需的 8 个字节相比。
乘以 10000 并存储为 BIGINT,如 Visual Basic 和 Office 中的“货币”。请参阅https://msdn.microsoft.com/en-us/library/office/gg264338.aspx
decimal
和numeric
是相同的。numeric(19,4)
用于财务记录,让您可以更好地发挥和轻松接受新请求。