使用ORM时十进制与int

时间:2014-05-27 10:47:53

标签: c# nhibernate orm oracle11g llblgen

我一直在使用ORM工具/代码生成器,我发现在将列映射到属性时,他们更喜欢使用decimalint值。使用十进制有什么好处吗?

数据库中的列类型是我认为创建为Number的默认Number(38, 0)

2 个答案:

答案 0 :(得分:8)

NUMBERNUMBER(38),其范围远远大于intInt32)(并且远大于long)。 double具有不同的舍入语义,因此decimal是首选,以避免错误和问题。如果ORM可以保证数据适合int,那么使用int可能会更高兴。

答案 1 :(得分:1)

Decimal是128位数据类型。 Int32是32位,并且对于通用而言太小,因为表通常具有溢出32位int的行计数。有些工具只是默认为NUMBER(38)或Oracle中的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