我想在 MySQL 数据库中存储许多记录。它们都包含货币价值。但我不知道每个人要插入多少位。
为此,我必须使用哪种数据类型?
VARCHAR或INT(或其他数字数据类型)?
12 回答
由于金钱需要精确的表示,因此不要使用仅近似的数据类型,例如float
. 您可以使用定点数字数据类型,例如
decimal(15,2)
15
是精度(包括小数位的值的总长度)2
是小数点后的位数
请参阅MySQL 数字类型:
当保持精确的精度很重要时使用这些类型,例如货币数据。
我更喜欢使用BIGINT
,并通过乘以 100来存储值,这样它就会变成整数。
例如,要表示 的货币值93.49
,该值应存储为9349
,同时显示该值我们可以除以 100并显示。这将占用更少的存储空间。
注意:
大多数情况下我们不执行currency * currency
乘法,如果我们正在执行,则将结果除以 100 并存储,以便它返回到正确的精度。
这取决于您的需要。
通常使用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 中占用 12 字节空间(每 9 位 4 字节)。
我们使用double
.
*喘气*
为什么?
因为它可以表示任何 15 位数字,而对小数点的位置没有限制。全部只有区区 8 个字节!
所以它可以表示:
0.123456789012345
123456789012345.0
...以及介于两者之间的任何东西。
这很有用,因为我们正在处理全球货币,并且double
可以存储我们可能会遇到的各种小数位数。
单个double
字段可以代表日元的999,999,999,999,999s,美元的9,999,999,999,999.99s,甚至比特币的9,999,999.99999999s
如果您尝试对 执行相同操作decimal
,则需要decimal(30, 15)
14 个字节。
注意事项
当然,使用double
并非没有注意事项。
然而,正如一些人倾向于指出的那样,这并不是准确性的损失。即使它double
本身在内部可能不精确到以 10 为底的系统,我们可以通过将我们从数据库中提取的值四舍五入到它的有效小数位来使其精确。如果需要的话。(例如,如果要输出,则需要以 10 为基数的表示。)
需要注意的是,任何时候我们使用它进行算术运算时,我们都需要在之前对结果进行规范化(通过将其四舍五入到有效的小数位):
- 对其进行比较。
- 将其写回数据库。
另一种警告是,与decimal(m, d)
数据库将阻止程序插入多于m
数字的数字不同,不存在这样的验证double
。一个程序可以插入一个用户输入的 20 位数的值,它最终会被默默地记录为一个不准确的数字。
如果需要 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
. DECIMAL(13,4)
表示 9 位 + 4 小数位(小数位)=> 4 + 2 字节 = 6 字节- 与存储所需的 8 个字节相比
BIGINT
。
乘以 10000 并存储为 BIGINT,如 Visual Basic 和 Office 中的“货币”。请参阅https://msdn.microsoft.com/en-us/library/office/gg264338.aspx