mysql decimal的應用

可能做程序的人都知道,float類型是可以存浮點數(即小數類型),但是float有個壞處,當你給定的數據是整數的時候,那麼它就以整數給你處理。這樣我們在存取貨幣值的時候自然遇到問題,我的default值爲:0.00而實際存儲是0,同樣我存取貨幣爲12.00,實際存儲是12.
幸好mysql提供了兩個數據類型:numeric和decimal,這兩種數據類型可以輕鬆解決上面的問題:
NUMERIC 和 DECIMAL 類型被 MySQL 以同樣的類型實現,這在 SQL92 標準中是允許的。他們用於保存對準確精度有重要要求的值,例如與金錢有關的數據。當以它們中的之一聲明一個列時,精度和數值範圍可以(通常是)被指定;例 如:

salary DECIMAL(5,2)

在這個例子中,5 (精度(precision)) 代表重要的十進制數字的數目,2 (數據範圍(scale)) 代表在小數點後的數字位數。在這種情況下,因此,salary 列可以存儲的值範圍是從 -99.99 到 99.99。(實際上 MySQL 在這個列中可以存儲的數值可以一直到 999.99,因爲它沒有存儲正數的符號)。

譯者注:

M 與D 對DECIMAL(M, D) 取值範圍的影響

類型說明 取值範圍(MySQL < 3.23) 取值範圍(MySQL >= 3.23)
=================================================
float,decimal精確度比較float,double容易產生誤差,對精確度要求比較高時,建議使用decimal來存,decimal在MySQL內存是以字符串存儲的,用於定義貨幣要求精確度高的數據。在數據遷移中,float(M,D)是非標準定義,最好不要這樣使用。M爲精度,D爲標度。

mysql>  create table t1(c1 float(10,2), c2 decimal(10,2),c3 float); // 10不包括小數點
mysql>  insert into t1 values(1234567.23, 1234567.23,1234567.23);
mysql>  select * from t1;
+------------+------------+---------+
| c1         | c2         | c3      |
+------------+------------+---------+
| 1234567.25 | 1234567.23 | 1234570 |
+------------+------------+---------+
1 row in set (0.00 sec)
 
mysql> insert into test02 values(9876543.21,9876543.22,9876543.21);
+------------+------------+---------+
| c1         | c2         | c3      |
+------------+------------+---------+
| 1234567.25 | 1234567.23 | 1234570 |
| 9876543.00 | 9876543.22 | 9876540 |
+------------+------------+---------+
2 rows in set (0.00 sec)
mysql>  insert into t1 values(1.21, 1.12,1.21);
+------------+------------+---------+
| c1         | c2         | c3      |
+------------+------------+---------+
| 1234567.25 | 1234567.23 | 1234570 |
| 9876543.00 | 9876543.22 | 9876540 |
|       1.21 |       1.12 |    1.21 |
+------------+------------+---------+
3 rows in set (0.01 sec)
 
mysql>  insert into t1 values(1.2, 1.2,1.2);
+------------+------------+---------+
| c1         | c2         | c3      |
+------------+------------+---------+
| 1234567.25 | 1234567.23 | 1234570 |
| 9876543.00 | 9876543.22 | 9876540 |
|       1.21 |       1.12 |    1.21 |
|       1.20 |       1.20 |     1.2 |
+------------+------------+---------+
4 rows in set (0.00 sec)

mysql>  insert into t1 values(9876543.216, 9876543.126,9876543.216);
+------------+------------+---------+
| c1         | c2         | c3      |
+------------+------------+---------+
| 1234567.25 | 1234567.23 | 1234570 |
| 9876543.00 | 9876543.22 | 9876540 |
|       1.21 |       1.12 |    1.21 |
|       1.20 |       1.20 |     1.2 |
| 9876543.00 | 9876543.13 | 9876540 |
+------------+------------+---------+
5 rows in set (0.00 sec)
 
mysql>  insert into t1 values(1.216, 1.126,1.216);
+------------+------------+---------+
| c1         | c2         | c3      |
+------------+------------+---------+
| 1234567.25 | 1234567.23 | 1234570 |
| 9876543.00 | 9876543.22 | 9876540 |
|       1.21 |       1.12 |    1.21 |
|       1.20 |       1.20 |     1.2 |
| 9876543.00 | 9876543.13 | 9876540 |
|       1.22 |       1.13 |   1.216 |
+------------+------------+---------+
6 rows in set (0.00 sec)

不定義fload, double的精度和標度時,存儲按給出的數值存儲,這於OS和當前的硬件有關。decimal默認爲decimal(10,0)因爲誤差問題,在程序中,少用浮點數做=比較,可以做range比較。如果數值比較,最好使用decimal類型。精度中,符號不算在內:

mysql> insert into t1 values(-98765430.21,-98765430.12,-98765430.21);

mysql> select * from t1;

+--------------+--------------+-----------+

| c1           | c2           | c3        |

+--------------+--------------+-----------+

|   1234567.25 |   1234567.23 |   1234570 |

|   9876543.00 |   9876543.22 |   9876540 |

|         1.21 |         1.12 |      1.21 |

|         1.20 |         1.20 |       1.2 |

|   9876543.00 |   9876543.13 |   9876540 |

|         1.22 |         1.13 |     1.216 |

| -98765432.00 | -98765430.12 | -98765400 |

+--------------+--------------+-----------+

7 rows in set (0.00 sec)

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章