NUMERIC / DECIMAL
JoachimIsakssonが言ったように
、 NUMERICを使用します / DECIMAL
タイプ、任意精度タイプとして。
NUMERICに関する2つの重要なポイント / DECIMAL :
- doc をお読みください デフォルトのスケールである0、つまり小数部が切り捨てられる整数値を回避するようにスケールを指定する必要があることを注意深く学習してください。これは、Postgresが標準SQLから逸脱する場所の1つです(実装の制限までスケールアップできます)。したがって、スケールを指定しないことは適切な選択ではありません。
- SQLタイプ
NUMERIC&DECIMAL近いが同一ではない SQL標準に準拠。 SQL:92 、NUMERICに指定した精度DECIMALの場合は尊重されますが、 データベースサーバーは、指定した精度を超える精度を追加できます。ここでも、Postgresは標準から少し外れており、両方のNUMERIC&DECIMAL文書化 同等のものとして。
条件:
- 精度は、数値の合計桁数です。
- スケールは、小数点の右側の桁数(小数)です。
- (精度-スケール)=小数点の左側の桁数(整数部分)。
精度と規模に関するプロジェクトの仕様を明確にします。
- 大きい
精度は、将来必要になる可能性のあるより大きな数値を処理するのに十分な大きさである必要があります。意味…おそらく、現在のアプリは数千米ドルで動作しますが、将来的には数百万ドルになるロールアップレポートを実行する必要があります。 - 小さい
会計上の目的によっては、最小通貨額の端数を保存する必要がある場合があります。意味…USD のペニーに必要な小数点以下2桁ではなく、小数点以下3桁または4桁以上 。
MONEYは避けてください タイプ
PostgresはMONEYを提供しています
タイプも。それは正しいように聞こえるかもしれませんが、おそらくほとんどの目的に最適ではありません。 1つの欠点は、MONEYを使用することです。 スケールはデータベース全体の構成設定によって設定されます ロケール
に基づく 。そのため、サーバーを切り替えたり、その他の変更を加えたりすると、設定が危険なほど簡単に変わる可能性があります。さらに、NUMERICの各列にスケールを設定することはできますが、特定の列に対してその設定を制御することはできません。 タイプ。最後に、MONEY このMONEYが含まれています 他のデータベースシステムからデータを移植する人々の便宜のために。
小数点を移動する
一部の人が採用しているもう1つの方法は、小数点を移動し、大きな整数のデータ型で格納することです。
たとえば、USD を保存する場合 1セント硬貨にドル、任意の小数を100倍し、整数型にキャストして続行します。たとえば、$123.45は整数12,345になります。
このアプローチの利点は、実行時間が短縮されることです。 sumなどの操作 整数で実行すると非常に高速です。整数のもう1つの利点は、メモリ使用量が少ないことです。
このアプローチは煩わしく、混乱し、危険だと思います。コンピュータはのために動作しているはずなので迷惑です 私たちに対してではなく、私たち。一部のプログラマーまたはユーザーは、乗算/除算を怠って小数に戻すことを怠り、誤った結果をもたらす可能性があるため、危険です。正確な小数を適切にサポートしていないシステムで作業している場合、このアプローチは許容できる回避策になる可能性があります。
DECIMALがある場合、小数点を移動することに利点はありません。 / NUMERIC SQLおよびBigDecimal
Javaで。
丸めとNaN
アプリのプログラミング、およびPostgresサーバー側で行われる計算では、丸めと切り捨てに十分注意して注意してください 小数で。そして、不注意によるNaNs をテストします。 ポップアップします。
アプリとPostgresの両方で、常に浮動小数点 を避けてください。 お金の仕事のためのデータ型。 浮動小数点はパフォーマンス速度のために設計されています 、ただし精度のコスト 。 計算の結果、小数部に一見クレイジーな余分な桁が含まれる可能性があります。正確さが重要な財務/金銭またはその他の目的には適していません。
BigDecimal
はい、Javaでは、BigDecimal
任意精度タイプとして。 BigDecimal 速度が遅く、より多くのメモリを使用しますが、金額を正確に保存します。 SQL NUMERIC / DECIMAL BigDecimalにマップする必要があります ここ
で説明されているように および
BigDecimal Javaの最も優れた点の1つです。同様のクラスを持つ他のプラットフォーム、特に、長年にわたって行われた主要な機能強化と修正を備えた、非常によく実装され、研ぎ澄まされたプラットフォームを私は知りません。
BigDecimalの使用 Javaの浮動小数点型
を使用するよりも明らかに低速です。 、float &double 。しかし、実際のアプリでは、あなたのお金の計算がボトルネックになるとは思えません。さらに、あなたとあなたの顧客のどちらが欲しいですか:最速 お金の計算、または正確 お金の計算? 😉
私はいつもBigDecimalについて考えてきました Javaの最大のスリーパー機能として、小数の高度なサポートが不足している他の多くのプラットフォームよりもJavaプラットフォームを使用することの最も重要な利点。
同様の質問:通貨に最適なデータ型