[쥔장]========================================================
mysql을 사용하는 중에 double 형 값을 가지고 일반적인 계산 및 자릿수 올림도 하고 하는데, 계속 값이 머릿속과 계산기에 두들기는 것과는 다르게 나오는 현상이 있어서 찾아보니,
제대로 된 계산 값을 가지기 위해서는 decimal로 쓰는 것이 맞는 것이였음.
하여 질의가 잘 정리된 것을 스크랩한다.
===============================================================
[http://stackoverflow.com/questions/6831217/double-vs-decimal-in-mysql]
32 10 | OK, so I know there are tons of articles stating I shouldn't use DOUBLE to store money on a MySQL database, or I'll end up with tricky precision bugs. The point is I am not designing a new database, I am ask to find way to optimise an existing system. The newer version contains 783 DOUBLE typed columns, most of them used to store money or formula to compute money amount. So my first opinion on the subject was I should highly recommend a conversion from DOUBLE to DECIMAL in the next version, because the MySQL doc and everybody say so. But then I couldn't find any good argument to justify this recommandation, for three reasons :
Even by performing operations on a 18 millons rows table, like SUM and complex multiplications, I couldn't perform a bug of lack of precision. And we don't actually do this sort of things in production. I can show the precision lost by doing something like
But I can't figure out a way to turn it into a bug at the 2nd decimal digit. Most of the real issues I found on the internet are 2005 and older forum entries, and I couldn't reproduce any of them on a 5.0.51 MySQL server. So as long as we do not perform any SQL arithmetic operations, which we do not plan to do, are there any issue we should expect from only storing and retreiving a money amount in a DOUBLE column ? | ||||||||
|
20 | Actually it's quite different. DOUBLE causes rounding issues. And if you do something like | ||||
|
15 | The example from MySQL documentation http://dev.mysql.com/doc/refman/5.1/en/problems-with-float.html (i shrink it, documentation for this section is the same for 5.5)
Basically if you sum a you get 0-13.2+59.6+30.4 = 76.8. If we sum up b we get 0+0+46.4+30.4=76.8. The sum of a and b is the same but MySQL documentation says:
If we repeat the same with decimal:
The result as expected is empty set. So as long you do not perform any SQL arithemetic operations you can use DOUBLE, but I would still prefer DECIMAL. Another thing to note about DECIMAL is rounding if fractional part is too large. Example:
| ||||||||
|
11 | We have just been going through this same issue, but the other way around. That is, we store dollar amounts as DECIMAL, but now we're finding that, for example, MySQL was calculating a value of 4.389999999993, but when storing this into the DECIMAL field, it was storing it as 4.38 instead of 4.39 like we wanted it to. So, though DOUBLE may cause rounding issues, it seems that DECIMAL can cause some truncating issues as well. | ||||||||||||
|
0 | "are there any issue we should expect from only storing and retreiving a money amount in a DOUBLE column ?" It sounds like no rounding errors can be produced in your scenario and if there were, they would be truncated by the conversion to BigDecimal. So I would say no. However, there is no guarantee that some change in the future will not introduce a problem. | ||
0 | From your comments,
Using the example in the comments, I might foresee a case where you have 400 sales of $1.47. Sales-before-tax would be $588.00, and sales-after-tax would sum to $636.51 (accounting for $48.51in taxes). However, the sales tax of $0.121275 * 400 would be $48.52. This was one way, albeit contrived, to force a penny's difference. I would note that there are payroll tax forms from the IRS where they do not care if an error is below a certain amount (if memory serves, $0.50). Your big question is: does anybody care if certain reports are off by a penny? If the your specs say: yes, be accurate to the penny, then you should go through the effort to convert to DECIMAL. I have worked at a bank where a one-penny error was reported as a software defect. I tried (in vain) to cite the software specifications, which did not require this degree of precision for this application. (It was performing many chained multiplications.) I also pointed to the user acceptance test. (The software was verified and accepted.) Alas, sometimes you just have to make the conversion. But I would encourage you to A) make sure that it's important to someone and then B) write tests to show that your reports are accurate to the degree specified. | ||||
|