货币值的最佳SQL数据类型是什么?我正在使用MySQL,但更喜欢数据库独立的类型。
Decimal(19,4)在大多数情况下工作得很好。您可以调整比例和精度,以适应您需要存储的数字的需要。即使在SQL Server中,我也不倾向于使用“money”,因为它是不标准的。
Assaf的回应
这取决于你有多少钱…
听起来很轻率,但实际上是相关的。
就在今天,我们遇到了一个问题,记录未能插入到我们的Rate表中,因为其中一列(GrossRate)被设置为Decimal(11,4),而我们的产品部门刚刚获得了一份合同,在Bora Bora的某个令人惊讶的度假胜地,每晚售价数百万太平洋法郎……这是10年前设计数据库模式时从未预料到的。
唯一需要注意的是,如果从一个数据库迁移到另一个数据库,你可能会发现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)
For accounting applications it's very common to store the values as integers (some even go so far as to say it's the only way). To get an idea, take the amount of the transactions (let's suppose $100.23) and multiple by 100, 1000, 10000, etc. to get the accuracy you need. So if you only need to store cents and can safely round up or down, just multiply by 100. In my example, that would make 10023 as the integer to store. You'll save space in the database and comparing two integers is much easier than comparing two floats. My $0.02.
非常晚进入,但GAAP是一个很好的经验法则。对货币字段应用DECIMAL(13,4)就足够了。
如果你的应用程序需要处理高达一万亿的货币价值,那么这应该工作:13,2如果你需要遵守GAAP(公认会计原则),那么使用:13,4 通常你应该把你的货币值加到13,4,然后把输出四舍五入到13,2。
在MySQL中,您可以使用DECIMAL或NUMERIC数据类型,因为它们存储精确的数值数据值。
使用13,4可以得到999,999,999.9999美元。根据ISO 4217,只有2个国家使用小数点后4位(智利和乌拉圭)。
来源:
ISO 4217 -定义用于表示货币的alpha和数字代码。 流通货币一览表 在MySQL中存储货币值的最佳数据类型
您可以在默认情况下对所有货币值使用DECIMAL(19,2)之类的值,但如果您只存储低于1,000美元的值,那么这将浪费宝贵的数据库空间。
对于大多数实现,DECIMAL(N,2)就足够了,其中N的值至少是。你期望存储在这个字段中的最大的总和中+ 5。因此,如果您不希望存储任何大于999999.99的值,DECIMAL(11,2)应该绰绰有余(直到期望发生变化)。
如果您希望符合GAAP,则可以使用DECIMAL(N,4),其中N的值至少是。在你期望存储在这个字段中的最大的总和中+ 7。
这取决于数据的性质。你需要事先考虑清楚。
我的情况
decimal(13,4) unsigned for recording money transactions storage efficient (4 bytes for each side of decimal point anyway) 1 GAAP compliant decimal(19,4) unsigned for aggregates we need more space for totals of multiple multi-billion transactions semi-compliance with MS Currency data type won't hurt 2 it will take more space per record (11 bytes - 7 left & 4 right), but this is fine as there are fewer records for aggregates 1 decimal(10,5) for exchange rates they are normally quoted with 5 digits altogether so you could find values like 1.2345 & 12.345 but not 12345.67890 it is widespread convention, but not a codified standard (at least to my quick search knowledge) you could make it decimal (18,9) with the same storage, but the datatype restrictions are valuable built-in validation mechanism
为什么(M, 4) ?
有些货币可以分成一千个便士 还有货币等价物,比如"Unidad de Fermento", "CLF"用四位有效小数点后3,4表示 它符合美国公认会计准则
权衡
低精度: 存储成本低 更快的计算 降低计算错误风险 更快的备份和恢复 更高的精度: 未来兼容性(数量趋于增长) 节省开发时间(当达到限制时,您不必重新构建半个系统) 由于存储精度不够,降低生产失败的风险
兼容的极端
虽然MySQL允许您使用十进制(65,30),但如果我们想要保留传输选项,31表示刻度,30表示精度似乎是我们的限制。
最常见RDBMS的最大规模和精度:
Precision Scale Oracle 31 31 T-SQL 38 38 MySQL 65 30 PostgreSQL 131072 16383
Six, seven, eight, nine
合理的极端
为什么(27岁,4)? 你永远不知道系统什么时候需要储存津巴布韦元
2015年9月,津巴布韦政府宣布将以1美元兑换35千万亿津巴布韦元5美元的汇率兑换津巴布韦元
我们倾向于说“是的,当然……我不需要那些疯狂的数字。”津巴布韦人以前也这么说。不久以前。
让我们想象一下,你需要记录一笔100万美元的津巴布韦元交易(今天可能不太可能,但谁知道10年后会是什么样子呢?)
(100万美元)* (35 Quadrylion ZWL) = (10^6) * (35 * 10^15) = 35 * 10^21 我们需要: 2位数字存储“35” 用21位数字来存储零 小数点右4位 这就得到了十进制(27,4),每个条目花费15个字节 我们可以免费在左边再加一位数字——我们用十进制(28,4)表示15字节 现在我们可以储存1000万美元的津巴布韦元交易,或者避免另一次高通胀的打击,希望不会发生
简单的回答:我建议使用十进制,精度根据您的需要。如果你想要存储整数的货币小单位(例如美分),并且在你的编程语言中处理小数有困难,可以选择精度= 0的Decimal。
为了找到所需的精度,你需要考虑以下几点:
您支持的货币类型(它们可以有不同数量的小数)。加密货币最多有18个小数(ETH)。由于通货膨胀,小数的数量可以随着时间的推移而改变。 存储小单位商品的价格(可能是从另一种货币转换的结果)或使用累加器可能需要使用比一种货币定义的更多的小数
如果您需要更改精度,则存储最小单元的整数可能导致将来需要重新缩放值。如果用小数,就简单多了。
文章中有更多细节和注意事项。
推荐文章
- 如何检查一个表是否存在于给定的模式中
- 添加一个复合主键
- 如何在SQL Server Management Studio中查看查询历史
- 无法添加或更新子行:外键约束失败
- 如何从本地机器mysqldump远程数据库
- 可以为公共表表达式创建嵌套WITH子句吗?
- 什么时候我需要在Oracle SQL中使用分号vs斜杠?
- SQL Server的NOW()?
- 在SQL中,count(列)和count(*)之间的区别是什么?
- 在SQL Server中截断(不是四舍五入)小数位
- 如何正确地创建复合主键- MYSQL
- 仅在Datetime列上按日期分组
- PostgreSQL通配符LIKE用于单词列表中的任何一个
- 在MySQL数据库中存储货币值的最佳数据类型
- 如何自定义'显示进程列表'在mysql?