Decimal vs. int when using ORMs
本文关键字:using ORMs when int vs Decimal | 更新日期: 2023-09-27 18:05:25
我一直在使用ORM工具/代码生成器,我看到他们在将列映射到属性时更喜欢使用decimal
到int
值。使用十进制有什么好处吗?
数据库中的列类型是默认的Number
,我认为创建为Number(38, 0)
。
NUMBER
是NUMBER(38)
,它的可能范围比int
(Int32
)大得多(也比long
大得多)。double
具有不同的舍入语义,因此首选decimal
以避免错误和问题。如果ORM可以保证数据适合int
,那么它可能更愿意使用int
。
Decimal是128位数据类型。Int32是32位的,对于一般用途来说太小了,因为表的行数通常会超过32位的int。有些工具在Oracle中只是默认为NUMBER(38)或INTEGER别名,它们映射到相同的别名,有些工具采取简单的方法并使用Decimal,而其他工具则尝试更接近相应的值范围。
考虑到Oracle NUMBER(38)可以有多大,(38位有效数字是一个很大的数字),Decimal是唯一安全的选择。但是,如果您知道要存储顺序值,那么Int64就足够实用了,因为即使是Decimal也可能溢出Oracle NUMBER。十进制最多可以容纳79,228,162,514,264,337,593,543,950,335。这是"只有"29位有效数字,仍然不能容纳NUMBER(38)的最大值。
如果你想要一个更接近的映射,你需要在Oracle中使用更小精度的NUMBER字段。我使用:
NUMBER(9) => Int32
NUMBER(18) => Int64
NUMBER(19+) => Decimal
在我写的数据访问代码生成器。orm可以做同样的事情,也可以不做。通常NUMBER(18)对于任何需要的整数键都是足够的。
如果你没有对你的主键进行算术运算,那么我不能想象使用Decimal类型有什么缺点,如果你只是想要"立即忘记",而不必担心不合适的值。在OLTP系统中,使用Decimal和Int64之间的性能差异可以忽略不计,并且Oracle并不关心您将字段定义为NUMBER(1)还是NUMBER(38),就数据存储而言,NUMBER()类型是像VARCHAR一样的可变长度类型,只会占用每行中特定值所需的尽可能多的空间。它不是一个固定长度的存储,所以实际上你只是限制了潜在的值,而不是节省空间。
SQL> insert into bbb values(1);
1 row created.
SQL> insert into bbb values(11111111);
1 row created.
SQL> insert into bbb values(1111111111111111111111111);
1 row created.
SQL> select i, vsize(i) from bbb;
I VSIZE(I)
---------- ----------
1 2
11111111 5
1.1111E+24 14