天天看點

MySQL DECIMAL資料類型

同僚問MySQL資料類型DECIMAL(N,M)中N和M分别表示什麼含義,M不用說,顯然是小數點後的小數位數,但這個N究竟是小數點之前的最大位數,還是加上小數部分後的最大位數?這個還真記不清了。于是乎,建立測試表驗證了一番,結果如下:

測試表,seller_cost字段定義為decimal(14,2)

CREATE TABLE `test_decimal` (
  `id` int() NOT NULL,
  `seller_cost` decimal(,) DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8
           

起初,表中内容為空

mysql> select * from test_decimal;
Empty set ( sec)
           

插入整數部分長度為14的數字,報超出列範圍的錯誤

mysql> insert into test_decimal(id,seller_cost) values(,);
ERROR  (): Out of range value for column 'seller_cost' at row 1
           

插入整數部分長度為12的數字,可以正确插入

mysql> insert into test_decimal(id,seller_cost) values(,);
Query OK, 1 row affected (0.00 sec)
           

查詢表,發現插入的整數值末尾被MySQL補了兩位小數“.00”

mysql> select * from test_decimal;
+----+-----------------+
| id | seller_cost     |
+----+-----------------+
|  1 | 123456789012.00 |
+----+-----------------+
1 row in set (0.00 sec)
           

繼續插入整數部分12位,小數部分5位的數字,可以成功插入,但是有警告,警告表明小數部分發生了截斷,被截取成了兩位小數

mysql> insert into test_decimal(id,seller_cost) values(1,123456789012.12345);
Query OK, 1 row affected, 1 warning (0.00 sec)

mysql> show warnings;
+-------+------+--------------------------------------------------+
| Level | Code | Message                                          |
+-------+------+--------------------------------------------------+
| Note  | 1265 | Data truncated for column 'seller_cost' at row 1 |
+-------+------+--------------------------------------------------+
1 row in set (0.00 sec)

mysql> select * from test_decimal;
+----+-----------------+
| id | seller_cost     |
+----+-----------------+
|  1 | 123456789012.00 |
|  1 | 123456789012.12 |
+----+-----------------+
2 rows in set (0.00 sec)
           

縮小整數部分的長度為2,小數部分的長度繼續保持為5,可以成功插入,但小數部分被截斷為兩位。

mysql> insert into test_decimal(id,seller_cost) values(1,12.12345);
Query OK, 1 row affected, 1 warning (0.00 sec)

mysql> show warnings;
+-------+------+--------------------------------------------------+
| Level | Code | Message                                          |
+-------+------+--------------------------------------------------+
| Note  | 1265 | Data truncated for column 'seller_cost' at row 1 |
+-------+------+--------------------------------------------------+
1 row in set (0.00 sec)

mysql> select * from test_decimal;
+----+-----------------+
| id | seller_cost     |
+----+-----------------+
|  1 | 123456789012.00 |
|  1 | 123456789012.12 |
|  1 |           12.12 |
+----+-----------------+
3 rows in set (0.00 sec)
           

繼續插入一個小數部分不足兩位的數字,可正确插入,且小數部分被自動補全到兩位。

mysql> insert into test_decimal(id,seller_cost) values(1,12.1);
Query OK, 1 row affected (0.00 sec)

mysql> select * from test_decimal;
+----+-----------------+
| id | seller_cost     |
+----+-----------------+
|  1 | 123456789012.00 |
|  1 | 123456789012.12 |
|  1 |           12.12 |
|  1 |           12.10 |
+----+-----------------+
4 rows in set (0.00 sec)
           

綜上所述,DECIMAL(N,M)中M值的是小數部分的位數,若插入的值未指定小數部分或者小數部分不足M位則會自動補到M位小數,若插入的值小數部分超過了M為則會發生截斷,截取前M位小數。N值得是整數部分加小數部分的總長度,也即插入的數字整數部分不能超過N-M位,否則不能成功插入,會報超出範圍的錯誤。

繼續閱讀