MySQL知識樹 數值類型 浮點數和定點數

浮點數和定點數數據庫

這二者都是用來表示小數的,浮點數包括float(單精度)、double(雙精度),定點數爲decimal。二者在定義時均可以指定其精度和標度,精度是指一共顯示多少位數字(整數位+小數位),標度是指精確到小數點後多少位,表現形式如:decimal(15,2),這裏的精度是15位(整數13位,小數2位),標度是2位。spa

須要說明的是定點數在MySQL內部是以字符串的形式來保存的,屬於準確存儲,3d

 

咱們建立一張表,字段id的數據類型爲decimal(5,2)blog

 

向表裏插入超過標度的值時,雖然插入成功可是MySQL有一個警告,查看數據咱們知道發生了四捨五入。ci

 

咱們再向表裏嘗試插入超過精度的值,難道也會發生截斷並四捨五入?兩個值會分別顯示爲123.12和124.12嗎?從結果來看明顯不是,咱們的猜想是徹底錯誤的。在超過精度的狀況下,雖然插入成功但插入的值倒是指定精度和標度下的最大值,例如(5,2)下的最大值爲999.99。字符串

如果在SQL Mode嚴格模式下,上述這些插入操做將不能被執行成功且MySQL會報ERROR。擴展

 

額外知識點:數據類型

如何理解單精度和雙精度?float

這二者的區別若是理解爲「單精度是精確到小數點後一位,而雙精度是精確到小數點後兩位」,那就大錯特錯了。實際上因爲float的有效位數是7位,double的有效位數是16位,所以單精度、雙精度實際上是指代這裏的有效位數。im

 

另外須要注意的是有效位數並不等於精確位數,縱然float能夠表示到小數點後7位,但只有前6位是精確的,第7位極可能形成數據偏差。而對於double來講只有前15位是精確的,第16位也極可能形成數據偏差。

 

額外知識點:

關於float、double精度丟失的問題,實際上就是被擴展或截斷了,究其原因是由於存取時標度不一致所致使的。在錄入數據時若數據的標度與定義列數據類型時設置的標度不一致,則會致使存入時以近似的值來存儲,這就形成了咱們上面說到的精度丟失。

 

那在什麼狀況下float、double的精度不會丟失呢?其實根據上面出問題的狀況,咱們能夠想到當數據標度與類型標度一致時(錄入數據的標度與定義列數據類型時設置的標度一致),就不會發生精度丟失。

 

鑑於此,咱們常選用decimal類型,小於等於其標度的數據都能被正確錄入,不會發生精度丟失,由於其是將數據以字符串的形式來存進數據庫的,這就保證了精確性。但並非說decimal就不會發生精度丟失,由於它雖然不會發生精度擴展但卻會發生精度截斷,例如當錄入數據的標度大於列數據類型設置的標度時,依然會發生四捨五入。

 

雖然咱們說decimal將數據以字符串的形式存入數據庫,同時又會存在精度截斷的問題(四捨五入),看似二者有文字描述上的衝突,其實否則。咱們這樣來理解:decimal將發生了四捨五入的數據以字符串的形式存入了數據庫,但表現出來的是小數(一個是存儲形式,一個是表現形式),且這個小數的精度不會再發生變化,而無論是以什麼精度來獲取這個值,它都是四捨五入後以字符串形式存入時的值。

相關文章
相關標籤/搜索