货币值的最佳SQL数据类型是什么?我正在使用MySQL,但更喜欢数据库独立的类型。
当前回答
Decimal(19,4)在大多数情况下工作得很好。您可以调整比例和精度,以适应您需要存储的数字的需要。即使在SQL Server中,我也不倾向于使用“money”,因为它是不标准的。
其他回答
Assaf的回应
这取决于你有多少钱…
听起来很轻率,但实际上是相关的。
就在今天,我们遇到了一个问题,记录未能插入到我们的Rate表中,因为其中一列(GrossRate)被设置为Decimal(11,4),而我们的产品部门刚刚获得了一份合同,在Bora Bora的某个令人惊讶的度假胜地,每晚售价数百万太平洋法郎……这是10年前设计数据库模式时从未预料到的。
这取决于数据的性质。你需要事先考虑清楚。
我的情况
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万美元的津巴布韦元交易,或者避免另一次高通胀的打击,希望不会发生
您可以在默认情况下对所有货币值使用DECIMAL(19,2)之类的值,但如果您只存储低于1,000美元的值,那么这将浪费宝贵的数据库空间。
对于大多数实现,DECIMAL(N,2)就足够了,其中N的值至少是。你期望存储在这个字段中的最大的总和中+ 5。因此,如果您不希望存储任何大于999999.99的值,DECIMAL(11,2)应该绰绰有余(直到期望发生变化)。
如果您希望符合GAAP,则可以使用DECIMAL(N,4),其中N的值至少是。在你期望存储在这个字段中的最大的总和中+ 7。
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中存储货币值的最佳数据类型
推荐文章
- 的类型不能用作索引中的键列
- SQL逻辑运算符优先级:And和Or
- 如何检查一个表是否存在于给定的模式中
- 添加一个复合主键
- 如何在SQL Server Management Studio中查看查询历史
- 无法添加或更新子行:外键约束失败
- 如何从本地机器mysqldump远程数据库
- 可以为公共表表达式创建嵌套WITH子句吗?
- 什么时候我需要在Oracle SQL中使用分号vs斜杠?
- SQL Server的NOW()?
- 在SQL中,count(列)和count(*)之间的区别是什么?
- 在SQL Server中截断(不是四舍五入)小数位
- 如何正确地创建复合主键- MYSQL
- 仅在Datetime列上按日期分组
- PostgreSQL通配符LIKE用于单词列表中的任何一个