2013-03-31 27 views

答えて

58

Numeric強制2単位精度です。通貨を表現するために浮動小数点型または浮動小数点型のデータ型を使用しないでください。そうした場合、財務報告の最終行の数字が+または - 数ドルで間違っていると、人々は不幸になります。

私が知る限り、お金の種類は歴史的な理由から残されています。

+1

それは浮動小数点を避ける理由ではありません。たとえどんな精度を使用していても、10のべき乗に分割されないもので除算すると、偶数の数値は丸め誤差を持つことになります。 (2の精度はとにかく悪い考えです。) – Doradus

39

選択肢は次のとおりです。

  1. integer:セントの量を格納します。これは、EFTPOSトランザクションが使用するものです。
  2. decimal(12,2):正確に小数点以下2桁の数値を格納します。これは、最も一般的な元帳ソフトウェアが使用するものです。
  3. float:恐ろしいアイデア - 不適切な精度。これは純粋な開発者が使用するものです。

オプション2が最も一般的で使いやすいです。私の例では12で、すべてで12桁の意味を持つ精度を、あなたに最適なものと同じくらい大きくても小さくてもかまいません。

計算結果(換算レートなど)の複数のトランザクションをビジネス上の意味を持つ単一の値に集約する場合、正確なマクロ値を提供するためには精度が高くなければならないことに注意してください。 decimal(18, 8)のようなものを使うことを考えてください。そのため、合計は正確で、個々の値は表示のためにセンチメートルの精度に丸められます。

+2

任意の種類の逆算税計算または外国為替を使用している場合は、小数点以下4桁以上が必要です。そうしないと、データが失われます。したがって、 '数値(15,4)'または '数値(15,6)'は良い考えです。 –

+1

4番目のオプションがあります。これは、文字列を使用し、ホスト言語で同等の非損失の10進数型を使用することです。 – ioquatix

72

あなたのソースは公式ではありません。それは2011年に始まり、私は著者を認識しません。お金の種類が "落胆"していた場合、PostgreSQLはマニュアルでwhich it doesn'tと言います。 については

より公式なソースは、ダーシーJMカイン(金型の原作者)とトム・レーンなどのコア開発者からの声明で、this thread in pgsql-general (from just this week!)をお読みください。

基本的には、moneyが持っているその(制限)使用する。 numericの利点はの性能です。

decimalは、Postgresのnumericのエイリアスです。

答え関連の最近のリリースの改善について(やコメントを!):個人的に

、私はinteger表すセントと通貨を保存したいです。言及されたオプションのどれよりも効率的です。

+3

メーリングリストには、お金の種類が少なくとも推奨されないという印象を与える議論がいくつかあります。例:http://postgresql.nabble.com/Money-type-todos-td1964190.html#a1964192 plus公平でなければなりません:バージョン8.2のマニュアル**は非推奨です** http://www.postgresql.org/docs/8.2/static/datatype-money.html –

+1

@a_horse_with_no_name:あなたのリンクはからのスレッドへのリンクです2007年は8.2が現在のバージョンで、 'money'型は実際には非推奨となっています。問題は修正され、そのタイプは後のバージョンで追加されました。個人的に私はCentsを表す 'integer'として通貨を格納するのが好きです。 –

+0

アーウィン、データベースの観点だけで正しい考え方かもしれません。しかし、PostgreSQL + Javaを組み合わせると、それは(私の経験から)まったく良いことではありません。あなたのコメントを読んで、私はほとんどの通貨フィールドでMONEYを使いましたが、今はこのJava例外が発生します: "** SQLExceptionが発生しました:org.postgresql.util.PSQLException:タイプdoubleの値が不正:2,500.00 **"。私はグーグルで、良い解決策を見つけていないので、今度はそれらをすべて数値または小数点に変更するという退屈な作業に入っています! –

8

私はと私の金銭的なフィールドのすべてを保つ:

numeric(15,6)

少しでもチャンスがあるのならば、多くの小数点以下の桁は、しかし、あなたは複数の通貨に対処する必要がありますことを持っている過度のようだあなたはよ変換するためにその精度が必要です。私が何を提示しているかに関わらず、私はいつも米ドルに保管します。このようにして、当日のコンバージョン率を考慮すると、他の通貨に簡単に変換することができます。

1通貨以外の決済を行うことができない場合は、最悪の場合は、ゼロを保存するためのスペースを無駄にすることです。

+0

これは切り捨てがないため、結果が正しくない可能性があります。ゼロ以外の値が意図せず残りの小数点以下の桁に漏れた場合(たとえば、0.333333ドルを含む価格フィールド)、3つのアイテムをそれぞれ0.33ドルで購入した結果が$ 0.99ではなく$ 1.00になる場合があります。 – Peteris

+0

Perterisので、代わりに何をお勧めしますか?この丸めでどれだけ精度を上げても、問題になる可能性があります。この方が理想的ではないとしても、私は単により良い方法を見つけられませんでした。 –

+0

ポイントを固定し、必要に応じて切り捨てます。あなたが「保存可能な」金額に達するとすぐに、顧客に提供される価格であり、それは適切なメトリクスでなければなりません。これは、ほとんどの場合、標準的な小売環境ではセントセントで行われます。異なるビジネスニーズがある場合(例:ユニットごとに大量の商品の価格)異なる設定があるかもしれませんが、*プレゼンテーションをストレージと一緒に扱わなければなりません* - 小数点以下で金額を表示する場合(またはその逆、あなたはまた、それを正確に、それ以下に保存する必要があります。 – Peteris

関連する問題