web-dev-qa-db-ja.com

NHibernateでNUMBER Oracleデータ型をマッピングするには、どの.NETデータ型が最適ですか?

Oracleの整数列にマッピングするために、decimalがNHibernateプロジェクトで使用される例をいくつか見てきました。現在、プログラムでintlongを使用しています。

decimal/intに対するlongの利点は何ですか?パフォーマンスは向上しますか?

45
Ilya Kogan

さまざまな例で、int/longの代わりにdecimalが使用されているのを見てきました。理由を理解しようとしています

これはおそらく、.NET decimalおよびOracle NUMBERマップが少し優れているlongおよびNUMBERよりも多く、さらに多くを提供するためです柔軟性。後の段階でOracle列にscaleを追加する場合、decimalを既に使用していればデータ型を変更する必要はありません。

decimalは確かにintおよびlongより遅いです。なぜなら、後者の2つはハードウェアでサポートされているからです。とはいえ、何らかの違いを生むには、かなりの量のデータを処理する必要があります。それがあなたが扱っているものであるならlongを使うべきだと私はまだ思います、そしてあなたはまたそれを表の列定義にそれを表させるべきです。 longなどのNUMBER(18,0)など。

decimalが少し良くマッピングされる理由は、longが64ビットであり、decimalが(のような)128ビットであるためです。

。NET

タイプ:decimal
おおよその範囲:±1.0×10 ^ −28から±7.9×10 ^ 28
精度:28-29有効数字

タイプ:long
範囲:–9,223,372,036,854,775,808〜9,223,372,036,854,775,807
精度:18(ulongの場合は19)有効数字

Oracle

NUMBERデフォルト 有効数字38桁まで、スケール0(整数)。

タイプ:[〜#〜] number [〜#〜]
範囲:+-1 x 10 ^ -130〜9.99 ... 9 x 10 ^ 125
精度:有効数字38桁

Microsoftは問題を認識しており、 notes

このデータ型はNUMBER(38)データ型のエイリアスであり、OracleDataReaderが整数値ではなくSystem.DecimalまたはOracleNumberを返すように設計されています。 .NET Frameworkデータ型を使用すると、オーバーフローが発生する可能性があります。

考えてみると、実際に必要なのは BigInteger です。これは、NUMBERのデフォルト値と同じ有効桁数を表すことができるためです。私は誰もそれをするのを見たことがないし、それは非常にまれな必要だと思うだろう。また、BigIntegerは正および負の無限大になる可能性があるため、NUMBERはそれをカットしません。

57
Jonas Elfström
[.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]  
39
Homam
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    
12
Carl Prothman