哪种 .NET 数据类型最适合在 NHibernate 中映射 NUMBER Oracle 数据类型?

发布于 2024-10-27 21:45:51 字数 186 浏览 2 评论 0原文

我见过一些在 NHibernate 项目中使用十进制来映射到 Oracle 中的整数列的示例。现在我在程序中使用 intlong

decimal 相对于 int/long 有哪些优势?它的性能更好吗?

I've seen some examples in which decimal is used in NHibernate projects for mapping to whole number columns in Oracle. Right now I'm using int and long in my program.

What are the advantages of decimal over int/long? Does it perform better?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

不一样的天空 2024-11-03 21:45:51

我在各种示例中看到过使用十进制而不是 int/long 。我只是想了解为什么

这可能是因为 .NET decimal 和 Oracle NUMBER 映射比 longNUMBER 更好一点,而且还为您提供了更大的灵活性。如果您稍后在 Oracle 列中添加小数位数,那么如果您已经使用了十进制,则无需更改数据类型。

decimal 肯定比 intlong 慢,因为硬件支持后两者。也就是说,您必须处理大量数据才能发挥作用。我仍然认为您应该使用 long 如果这就是您正在处理的内容,那么您还应该让表列定义来表示它。 NUMBER(18,0) 表示 long 等等。

decimal 映射得更好一点的原因是 long 是 64 位,而 decimal 是(某种)128 位。

.NET

<块引用>

类型:十进制
近似范围:±1.0 × 10^−28 至 ±7.9 × 10^28
精度:28-29位有效数字

类型:
范围:–9,223,372,036,854,775,808 至 9,223,372,036,854,775,807
精度:18 位(ulong 为 19 位)有效数字

Oracle

NUMBER 默认为 38 位有效数字,小数位数为 0(整数)。

<块引用>

类型:数字
范围:+/- 1 x 10^-130 至 9.99...9 x 10^125
精度:38位有效数字

Microsoft 已意识到该问题并注释

该数据类型是
NUMBER(38) 数据类型,并且被设计
这样 OracleDataReader 返回一个
改为 System.Decimal 或 OracleNumber
一个整数值。使用.NET
框架数据类型可能会导致
溢出。

想想看,您实际上需要 BigInteger 能够表示与 NUMBER 默认值相同的有效数字。我从未见过有人这样做,我认为这是一个非常罕见的需求。而且 BigInteger 仍然不会削减它,因为 NUMBER 可以是正无穷大和负无穷大。

I've seen decimal used instead of int/long in various examples. I'm just trying to understand why

That's probably because .NET decimal and Oracle NUMBER maps a bit better than long and NUMBER and it also gives you more flexibility. If you at a later stage add a scale in the Oracle column then you wouldn't have to change datatype if you already used decimal.

decimal is certainly slower than int and long since the later two are supported in hardware. That said, you have to crunch some serious amount of data for it to make any difference. I still think that you should use long if that that's what you're dealing with and then you should also let the table column definitions represent that. NUMBER(18,0) for long and so on.

The reason decimal maps a little better is that long is 64 bits and decimal is (kind of) 128 bits.

.NET

Type: decimal
Approximate Range: ±1.0 × 10^−28 to ±7.9 × 10^28
Precision: 28-29 significant digits

Type: long
Range: –9,223,372,036,854,775,808 to 9,223,372,036,854,775,807
Precision: 18 (19 for ulong) significant digits

Oracle

NUMBER defaults to 38 significant digits and scale 0 (integer).

Type: NUMBER
Range: +- 1 x 10^-130 to 9.99...9 x 10^125
Precision: 38 significant digits

Microsoft is aware of the problem and notes

This data type is an alias for the
NUMBER(38) data type, and is designed
so that the OracleDataReader returns a
System.Decimal or OracleNumber instead
of an integer value. Using the .NET
Framework data type can cause an
overflow.

Come to think of it you actually need BigInteger to be able to represent the same number of significant digits as to what NUMBER defaults to. I've never seen anyone do that and I would suppose it's a very rare need. Also BigInteger still wouldn't cut it since NUMBER can be of positive and negative infinity.

傾城如夢未必闌珊 2024-11-03 21:45:51
[.NET: Int32] = [Oracle:NUMBER(2)..NUMBER(9)*] 
[.NET: Int64] = [Oracle:NUMBER(10)..NUMBER(18)*]
[.NET: Double] = [Oracle:NUMBER(x, 0)..NUMBER(x, 15)*]
[.NET: Double] = [Oracle: FLOAT]
[.NET: Decimal] = [Oracle:NUMBER]  
[.NET: Int32] = [Oracle:NUMBER(2)..NUMBER(9)*] 
[.NET: Int64] = [Oracle:NUMBER(10)..NUMBER(18)*]
[.NET: Double] = [Oracle:NUMBER(x, 0)..NUMBER(x, 15)*]
[.NET: Double] = [Oracle: FLOAT]
[.NET: Decimal] = [Oracle:NUMBER]  
墨落成白 2024-11-03 21:45:51
NUMBER(1,0)     => Boolean          
NUMBER(5,0)     => Int16/short.MaxValue == 32767    
NUMBER(10,0)    => Int32/int.MaxValue == 2,147,483,647    
NUMBER(19,0)    => Int64/long.MaxValue == 9,223,372,036,854,775,807    
NUMBER(1,0)     => Boolean          
NUMBER(5,0)     => Int16/short.MaxValue == 32767    
NUMBER(10,0)    => Int32/int.MaxValue == 2,147,483,647    
NUMBER(19,0)    => Int64/long.MaxValue == 9,223,372,036,854,775,807    
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文