1.首先,對于精度比較高的東西,比如money,我會(huì)用decimal類型,不會(huì)考慮float,double,因?yàn)樗麄內(nèi)菀桩a(chǎn)生誤差,numeric和decimal同義,numeric將自動(dòng)轉(zhuǎn)成decimal。
DECIMAL從MySQL 5.1引入,列的聲明語法是DECIMAL(M,D)。在MySQL 5.1中,參量的取值范圍如下:
·M是數(shù)字的最大數(shù)(精度)。其范圍為1~65(在較舊的MySQL版本中,允許的范圍是1~254),M 的默認(rèn)值是10。
·D是小數(shù)點(diǎn)右側(cè)數(shù)字的數(shù)目(標(biāo)度)。其范圍是0~30,但不得超過M。
說明:float占4個(gè)字節(jié),double占8個(gè)字節(jié),decimail(M,D)占M+2個(gè)字節(jié)。
如DECIMAL(5,2) 的最大值為9 9 9 9 . 9 9,因?yàn)橛? 個(gè)字節(jié)可用。
M 與D 對DECIMAL(M, D) 取值范圍的影響
類型說明取值范圍(MySQL < 3.23)取值范圍(MySQL >= 3.23)
MySQL < 3.23 MySQL >=3.23
DECIMAL(4, 1) -9.9 到 99.9 -999.9 到 9999.9
DECIMAL(5,1) -99.9 到 999.9 -9999.9 到 99999.9
DECIMAL(6,1) -999.9 到 9999.9 -99999.9 到 999999.9
DECIMAL(6,2) -99.99 到 999.99 -9999.99 到 99999.99
DECIMAL(6,3) -9.999 到 99.999 -999.999 到 9999.999
# 在MySQL 3.23 及以后的版本中,DECIMAL(M, D) 的取值范圍等于早期版本中的DECIMAL(M + 2, D) 的取值范圍。
結(jié)論:
當(dāng)數(shù)值在其取值范圍之內(nèi),小數(shù)位多了,則直接截?cái)嘈?shù)位。
若數(shù)值在其取值范圍之外,則用最大(小)值對其填充。
關(guān)于mysql5.6 decimal 類型的幾個(gè)小bug
bug 詳情見官介紹:
http://bugs.MySQL.com/bug.PHP?id=72056 (1)當(dāng)存儲(chǔ)的decimal值超級大的時(shí)候,在沒有索引的情況下,mysql會(huì)認(rèn)為所有的值一樣大
http://bugs.mysql.com/bug.php?id=72274 (2)當(dāng)使用decimal 做分區(qū)key的時(shí)候,分區(qū)key無法正確過濾分區(qū)的問題
一,關(guān)于bug (1)
創(chuàng)建測試表:
CREATE TABLE `decimalTest`(`value` DECIMAL(24,0) NOT NULL);
插入測試數(shù)據(jù):
INSERT INTO `decimalTest`(`value`) VALUES('100000000000000000000001'), ('100000000000000000000002'), ('100000000000000000000003');
INSERT INTO `decimalTest`(`value`) VALUES('1234'),('5678');
執(zhí)行查詢:
(a),字符串?dāng)?shù)字巨大值做條件:
SELECT * FROM `decimalTest` WHERE `value` = '100000000000000000000002';
+--------------------------+
| value |
+--------------------------+
| 100000000000000000000001 |
| 100000000000000000000002 |
| 100000000000000000000003 |
+--------------------------+
查詢結(jié)果不對
(b),數(shù)值數(shù)字巨大值做條件:
SELECT * FROM `decimalTest` WHERE `value` = 100000000000000000000002;
+--------------------------+
| value |
+--------------------------+
| 100000000000000000000002 |
+--------------------------+
查詢結(jié)果正確
==================這一部分是自己添加的,為了對比測試======================
(c)字符串?dāng)?shù)值小值做條件
select * from `decimalTest` WHERE `value` ='1234';
+-------+
| value |
+-------+
| 1234 |
+-------+
查詢結(jié)果正確
=======================================================================
(d)對字段添加索引,然后重新執(zhí)行(a)查詢
alter table decimalTest add index ind_decimal (`value`);
SELECT * FROM `decimalTest` WHERE `value` = '100000000000000000000002';
+--------------------------+
| value |
+--------------------------+
| 100000000000000000000002 |
+--------------------------+
結(jié)果正確
總結(jié):當(dāng)使用超大字符串?dāng)?shù)值作為條件查詢時(shí),mysql會(huì)將他們認(rèn)為一樣大,這個(gè)時(shí)候需要加索引才可以避免錯(cuò)誤,該bug在5.5、5.6都存在目前沒有修復(fù)
MySQL中的float和decimal類型有什么區(qū)別
decimal 類型可以精確地表示非常大或非常精確的小數(shù)。大至 1028(正或負(fù))以及有效位數(shù)多達(dá) 28 位的數(shù)字可以作為 decimal類型存儲(chǔ)而不失其精確性。該類型對于必須避免舍入錯(cuò)誤的應(yīng)用程序(如記賬)很有用。
float是浮點(diǎn)數(shù),不能指定小數(shù)位。
decimal是精確數(shù),可以指定精度。
對mysql 5來說 decimal(p,s)中p最大為65,S最大為30
decimal數(shù)據(jù)類型最多可存儲(chǔ) 38 個(gè)數(shù)字,它存儲(chǔ)了一個(gè)準(zhǔn)確(精確)的數(shù)字表達(dá)法,不存儲(chǔ)值的近似值。
當(dāng)數(shù)據(jù)值一定要按照指定精確存儲(chǔ)時(shí),可以用帶有小數(shù)的decimal數(shù)據(jù)類型來存儲(chǔ)數(shù)字。
float和real數(shù)據(jù)類型被稱為近似的數(shù)據(jù)類型。不存儲(chǔ)精確值.當(dāng)要求精確的數(shù)字狀態(tài)時(shí),比如在財(cái)務(wù)應(yīng)用程序中,在那些需要舍入的操作中,或在等值核對的操作中,就不使用這些數(shù)據(jù)類型。這時(shí)就要用integer、decimal、money或smallmone數(shù)據(jù)類型。
在 WHERE 子句搜索條件中(特別是 = 和 <> 運(yùn)算符),應(yīng)避免使用float或real列。最好限制使用float和real列做> 或 < 的比較。
float,double容易產(chǎn)生誤差,對精確度要求比較高時(shí),建議使用decimal來存,decimal在mysql內(nèi)存是以字符串存儲(chǔ)的,用于定義貨幣要求精確度高的數(shù)據(jù)。在數(shù)據(jù)遷移中,float(M,D)是非標(biāo)準(zhǔn)定義,最好不要這樣使用。M為精度,D為標(biāo)度。
mysql> create table t1(c1 float(10,2), c3 decimal(10,2));
Query OK, 0 rows affected (0.02 sec)
mysql> insert into t1 values(1234567.23, 1234567.23);
Query OK, 1 row affected (0.01 sec)
mysql> select * from t1;
+————+————+
| c1 | c3 |
+————+————+
| 1234567.25 | 1234567.23 |
+————+————+
1 row in set (0.02 sec)
mysql> insert into t1 values(9876543.21, 9876543.12);
Query OK, 1 row affected (0.00 sec)
mysql>
mysql> select * from t1;
+————+————+
| c1 | c3 |
+————+————+
| 1234567.25 | 1234567.23 |
| 9876543.00 | 9876543.12 |
+————+————+
2 rows in set (0.00 sec)
不定義fload, double的精度和標(biāo)度時(shí),存儲(chǔ)按給出的數(shù)值存儲(chǔ),這于OS和當(dāng)前的硬件有關(guān)。
decimal默認(rèn)為decimal(10,0)
因?yàn)檎`差問題,在程序中,少用浮點(diǎn)數(shù)做=比較,可以做range比較。如果數(shù)值比較,最好使用decimal類型。
精度中,符號(hào)不算在內(nèi):
mysql> insert into t1 values(-98765430.21, -98765430.12);
Query OK, 1 row affected (0.01 sec)
mysql> select * from t1;
+————–+————–+
| c1 | c3 |
+————–+————–+
| 1234567.25 | 1234567.23 |
| 9876543.00 | 9876543.12 |
| -98765432.00 | -98765430.12 |
+————–+————–+
3 rows in set (0.00 sec)
float占4個(gè)字節(jié),double占8個(gè)字節(jié),decimail(M,D)占M+2個(gè)字節(jié)。
Navicat 中decimal怎么設(shè)置小數(shù)位數(shù)
