2016-05-09 14 views
3

私は現在、(4.20と$ 4.2保存)ストア価格データにdecimalを使用していますが、それは平等を比較するためにいくつかのdifficultsを持つと思われる、すなわち、むしろそうnumber1 == number2Mysqlに価格を10進数または整数として保存する必要がありますか?

を使用するよりも2つの数字(abs(number1 - number 2) < 0.01)との間に別のを計算する必要があります私はそれが整数として価格を格納する方が良いかどうか疑問に思っています。例えば420ドルという店舗は400ドルです。

ありがとう。

+2

私は、MySQLが10進数を比較するのに問題があるとは思わない。おそらくあなたのプログラミング言語で起こり、浮動小数点に変換する場合にのみ起こります。それをしないでください。利用可能なBigDecimalのようなものがない場合は、それを避けるために 'select price * 100'を考慮してください。 – Thilo

+0

だから最終的に何を解決しましたか/ – e4c5

答えて

2

マイナー通貨を使用することができます。これは基本的に$ 4.20を420として格納しています。これは支払い処理ゲートウェイまたはAPIと通信する際に一般的に適用される方法です。

利点は、データベースとストレージ内のすべての算術演算が、小数ではなく整数を使用して行われることです。つまり、スペースが少なくて済み、操作がより速くなります。

としては、あなたがまた時々表示時に。

クリープできる浮動小数点errosを避ける@thiloによって指摘、単に正確に4.20を格納する100

+1

そして、最も重要なことは、浮動小数点数の問題を回避することです。丸め誤差)が発生します。 – Thilo

+0

@thiloさん、ありがとうございました。 – e4c5

2

DECIMAL(8,2)で割ます。比較などの問題はありません。(8,2)は最大100万ドルの価値をもたらします。必要に応じて調整してください。 MySQL 5.7 Reference Manualから

+0

mySQLの小数点以下の桁数をpythonの小数点以下の桁数と比較すると、問題が発生します。つまり、mySQLからデータを抽出し、Pythonで平等を比較します。 – Harrison

2

もう一つの方法は、正確な近似値の扱いの違いを見るためには、合計何倍に小さな数を追加することです。次のストアドプロシージャを考えてみましょう.0001を変数に1,000回追加します。

CREATE PROCEDURE p() 
BEGIN 
    DECLARE i INT DEFAULT 0; 
    DECLARE d DECIMAL(10,4) DEFAULT 0; 
    DECLARE f FLOAT DEFAULT 0; 
    WHILE i < 10000 DO 
    SET d = d + .0001; 
    SET f = f + .0001E0; 
    SET i = i + 1; 
    END WHILE; 
    SELECT d, f; 
END; 

dとfの両方の合計は論理的に1にする必要がありますが、これは小数点の計算にのみ適用されます。浮動小数点演算は、小さな誤差が導入されています

+--------+------------------+ 
| d  | f    | 
+--------+------------------+ 
| 1.0000 | 0.99999999999991 | 
+--------+------------------+ 

浮動小数点型を扱うときあなたが書くかについての問題が常に存在しています。確かに、MySQLに格納されている量がFLOATまたはDOUBLEの場合、この問題が発生しますが、これはちょうどDECIMALです。

DECIMALを使用している場合は、データベースで通常の比較を使用できます。 MySQLは誤った結果を返しません。

ただし、データベースからデータを取得し、プログラミング言語の変数に割り当てるときは注意が必要です。特に変数の動的型付けであるプログラミング言語の場合... integerまたはlong integerで操作する値を100倍して操作する必要があります。また、特殊なライブラリを使用してカンマ...

関連する問題