MySQLデータベースに通貨値を格納するための最適なデータ型


回答:


227

Decimal(19,4)ほとんどの場合、通常のようなものはかなりうまく機能します。格納する必要のある数値のニーズに合わせて、スケールと精度を調整できます。SQL Serverでも、「money」は非標準であるため使用しない傾向があります。


52
サイズに関するポイント:MSDN(msdn.microsoft.com/en-us/library/ms187746.aspx)によれば、Decimal(10,4)とDecimal(19,4)はどちらも9バイトのストレージを使用するため、スケールの余分な9桁のためによく春。
Adam Nofsinger

1
MSDNの記事はSQL Serverに関するものですが、問題はMySQLに関するものです。(私は明確にするために両方が同じであると最高に考える開発者に会いました。)
cja '19

5
(19,4)代わりに使用する利点は何(19,2)ですか?
ryvantage 2016年

1
私の利点はこれでした。特定の金額と同じになるようにすべてのテーブル行が必要でした。金額が$ 10.00であるとします。新しい行が追加されると、各行の量が変化します。テーブルに3つの行がある場合。10/3 = 3.3333333333 ...しかし、小数点以下2桁のみで、3.33として保存されます。これらを合計すると、3.33 + 3.33 + 3.33 = 9.99になります。ペニーを失った!大きなデータセットではさらに悪化します。19,4で保存してから出力ラウンド19,2に、あなたの合計を合計...
リック・

49

注意しなければならない唯一のことは、あるデータベースから別のデータベースに移行する場合、DECIMAL(19,4)とDECIMAL(19,4)が異なることを意味する場合があります。

http://dev.mysql.com/doc/refman/5.1/en/precision-math-decimal-changes.html

    DBASE:10,5(10整数、10進数5)
    MYSQL:15,5(15桁、10整数(15-5)、5桁の10進数)

リンクは今、残念ながら死んでいます。
MarcoAurélioDeleu

1
@MarcoAurélioDeleu -あなたは2009年に見えたバックとしてそれを見ることができるように私は、ウェイバックマシン上のページへのポイントへのリンクを変更しました
トニー・

17

計算に必要な小数点以下の桁数を計算することも重要です。

100万株の価格の計算を必要とする株価アプリケーションに取り組みました。引用された株価は7桁の精度で保存されなければなりませんでした。


7
それは良い点です-特に金融アプリでは、 "価格"は確かに "お金"を意味しない
Mike Woodhouse

17

アサフの反応

あなたがどれだけのお金を得たかによります...

軽快に聞こえますが、実際には適切です。

今日のみ、列の1つ(GrossRate)がDecimal(11,4)に設定されており、製品部門がいくつかの素晴らしいリゾートの部屋の契約を結んだため、Rateテーブルにレコードを挿入できないという問題がありましたボラボラ島では、1泊あたり数百万パシフィックフランで販売されています。データベーススキーマが10年前に設計されたときには、決して時代遅れになることはありませんでした。


2
これが、10進数を推奨した理由です(19,4)。やり過ぎのように聞こえるかもしれませんが、そのフィールドに本当に大量のデータを格納する必要があるときはわかりません。
Kibbee 2009年

2
@Kibbee:今日まで、私たちはあなたの要件についてあなたに同意しなかったでしょう。(6年間(11,4)は完璧でした...)
スコットファーガソン

@Kibbeeこれは640 Kbのミームのように聞こえます:)
Nikita

13

会計アプリケーションの場合、値を整数として格納することは非常に一般的です(それが唯一の方法であるとさえ言う人もいます)。アイデアを得るには、トランザクションの量(100.23ドルと仮定しましょう)を100、1000、10000などで乗算して、必要な精度を取得します。したがって、セントのみを格納する必要があり、安全に切り上げまたは切り捨てできる場合は、100を掛けるだけです。私の例では、格納する整数は10023になります。データベースのスペースを節約し、2つの整数を比較する方が2つの浮動小数点数を比較するよりもはるかに簡単です。私の0.02ドル。


6.125(6 1/8)はどのように保存しますか?
PeterToTheThird 2014年

私は彼が整数6125としてそれを格納します推測
ジミーKnoot

2
これはどうDECIMALですか?ペニー、ミル、またはミルレイを適切なタイミングで常にドルに変換することについては、非常に注意する必要があります。

MySQLの最新バージョンであっても、通常、パフォーマンスはDECIMALよりもINTの方が高速です。これらの値をPHPなどに取り込み、値を比較する必要がある場合にも、より簡単です。
Dane Bendixen、

9

非常に遅いエントリーですが、GAAPは大体の目安です。

アプリケーションが1兆までの金額の値を処理する必要がある場合、これは機能します。13、2 GAAP(一般に認められた会計原則)に準拠する必要がある場合は、次を使用します:13,4

通常、出力を13,2に丸める前に、金額を13,4で合計する必要があります。

ソース:MySQLに金銭的価値を保存するのに最適なデータ型


5

DECIMAL(19,2)すべての金額の値にデフォルトのようなものを使用することができますが、1,000ドル未満の値のみを保存する場合は、貴重なデータベース領域の無駄になります。

ほとんどの実装でDECIMAL(N,2)は十分です。ここで、の値Nは、少なくとも、.そのフィールドに格納されることが予想される最大の合計の前の桁数です+ 5。したがって、999999.99より大きい値を格納することを予期していない場合は、DECIMAL(11,2)(期待値が変わるまで)十分すぎるはずです。

GAAP準拠にしたい場合は、を使用できますDECIMAL(N,4)。ここで、の値Nは、少なくとも、.そのフィールドに格納されると予想される最大の合計の前の桁数です+ 7


3

データの性質によって異なります。事前に熟考する必要があります。

私の場合

  • decimal(13,4)は、通貨取引を記録するために符号なし
    • ストレージ効率(とにかく小数点の両側に4バイト)1
    • GAAP準拠
  • 集約の場合、decimal(19,4)符号なし
    • 複数の数十億のトランザクションの合計のためにより多くのスペースが必要です
    • MS Currencyデータ型に準準拠しても問題はありません2
    • レコードごとにより多くのスペースが必要になります(11バイト-左7と右4)。ただし、集約のレコードが少ないため、これは問題ありません1
  • 為替レートはdecimal(10,5)
    • 通常、これらはすべて5桁で引用されているため、1.2345&12.345などの値は検索できますが、12345.67890は検索できません。
    • それは広く使われている慣習ですが、体系化された標準ではありません(少なくとも私のクイックサーチの知識として)
    • 同じストレージで10進数(18,9)にすることもできますが、データ型の制限は組み込みの有効な検証メカニズムです。

なぜ(M、4)?

  • 千ペニーに分かれる通貨があります
  • 4つの重要な小数点以下の桁数で表す「UnidadデFERMENTO」、「CLF」などの金銭同等物がある3図4は、
  • GAAPに準拠しています

トレード・オフ

  • より低い精度:
    • 保管コストの削減
    • より迅速な計算
    • 計算エラーのリスクが低い
    • より迅速なバックアップと復元
  • より高い精度:
    • 将来の互換性(数は増える傾向がある)
    • 開発時間の節約(制限が満たされている場合、システムの半分を再構築する必要はありません)
    • 保管精度が不十分であるために生産が失敗するリスクが低い

互換性のあるエクストリーム

MySQLではdecimal(65,30)を使用できますが、転送オプションを開いたままにしたい場合は、スケールに31、精度に30を使用するのが制限のようです。

最も一般的なRDBMSの最大スケールと精度:

            精密スケール
オラクル31 31
T-SQL 38 38
MySQL 65 30
PostgreSQL 131072 16383

6789

合理的な極端

  1. なぜ(27,4)?
    • システムがジンバブエドルをいつ保管する必要があるかは決してわかりません

2015年9月ジンバブエ政府は、ジンバブエドルを1米ドルから35兆5,000億ドルのレートで米ドルに交換すると発表した5

私たちは「うん、確かに……あの狂った数字は必要ない」と言う傾向がある。まあ、ジンバブエ人もそう言っていた。それほど昔ではない。

ジンバブエドルで1百万USDのトランザクションを記録する必要があると想像してみてください(今日ではありそうにないかもしれませんが、これが10年後にどのようになるか知っていますか?)。

  1. (1百万米ドル)*(35 Quadrylion ZWL)=(10 ^ 6)*(35 * 10 ^ 15)= 35 * 10 ^ 21
  2. 必要です:
    • 「35」を格納する2桁
    • ゼロを格納するための21桁
    • 小数点以下4桁
  3. これにより、decimal(27,4)になり、エントリごとに15バイトのコストがかかります
  4. 無料で左側にもう1桁追加できます-15バイトにdecimal(28,4)があります
  5. これで、ジンバブエドルで表された10百万米ドルのトランザクションを保存できるようになりました。

0

これは遅いかもしれませんが、誰かに役立つでしょう。私の経験と研究から、私はdecimal(19、6)を知り、受け入れるようになりました。高い金額と為替レートで作業する場合

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.