可能做程序的人都知道,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)