decimal类型说明
01:decimal不存在精度损失,用于金钱帐目计算
02:格式:decimal(M.D),M表示长度(整数位+小数数总共的长度),D表示小数位的位数;
03:M不指定时的最大长度为65(65个9,包含了D的长度,真实的是35个9),D不指定时的最大长度为30(30个9),若指定了话,它的范围如04、05步骤所例;
04:格式:decimal(6,2) 没有unsigned或zerofill参数时,它的范围是-9999.99至9999.99,若加了unsigned或zerofill参数时,它的范围就是0至9999.99
05:格式:decimal(7,2) 没有unsigned或zerofill参数时,它的范围是-99999.99至99999.99若加了unsigned或zerofill参数时,它的范围就是0至99999.99
06:当插入的值(整数位的长度超过M-D时)直接报错
07:当插入的值(整数位的长度没有超过M-D的长度时,小数位超过了D的长度)会对小数位进行四舍五入(若整数位和小数位都是9,且整数位的长度+小数位的长度等于M时,那么不会四舍五入,因为范围决定了的)来达到你指定的小数位的长度;
08:当插入的值(整数位的长度没有达到M-D的长度时),若你在建表时指定了zerofill参数时,会把整数位进行前导0填充,以其让达到M-D的长度,若建表时没有加zerofill参数,则不会
创建chenliang库
mysql> create database if not exists chenliang character set utf8 collate utf8_general_ci;
Query OK, 1 row affected (0.01 sec)
mysql> show databases like "chenliang";
+----------------------+
| Database (chenliang) |
+----------------------+
| chenliang |
+----------------------+
1 row in set (0.00 sec)
mysql> use chenliang;
Database changed
mysql> select database();
+------------+
| database() |
+------------+
| chenliang |
+------------+
1 row in set (0.00 sec)
测试一:创建test1表,salary列使用decimal类型,指定长度(6,2),指定unsigned参数,不指定zerofill参数(前导师0填充)
-- 创建test1表
mysql> create table if not exists test1(
-> id int(10) unsigned not null auto_increment primary key comment"序列号",
-> name varchar(20) not null comment"姓名",
-> salary decimal(6,2) unsigned not null comment"工资" -- 注意这一列,类型为decimal,加了unsigned参数的哈
-> )engine=innodb character set utf8 collate utf8_general_ci;
Query OK, 0 rows affected (0.01 sec)
-- 查看test1表的表结构
mysql> desc test1;
+--------+-----------------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+--------+-----------------------+------+-----+---------+----------------+
| id | int(10) unsigned | NO | PRI | NULL | auto_increment |
| name | varchar(20) | NO | | NULL | |
| salary | decimal(6,2) unsigned | NO | | NULL | |
+--------+-----------------------+------+-----+---------+----------------+
3 rows in set (0.00 sec)
-- 第一阶段验证数据
insert into test1(name,salary) values("chenliang01",4000); -- 显示结果为4000.00[因为你插入的值4000位没有超过整数位的长度4(6-2),后面的小数会自动补全(因为你建表时指定了小数位是2位)]
insert into test1(name,salary) values("chenliang02",4000.234); -- 显示结果为4000.23[你插入的值4000.234总位数(整数位加小数位)超过了6位,且还是小数位超过了指定的位数(2位),把以会把小数位给四舍五入了]
insert into test1(name,salary) values("chenliang03",4000.236); -- 显示结果为4000.24[你插入的值4000.236总位数(整数位加小数位)超过了6位,且还是小数位超过了指定的位数(2位),把以会把小数位给四舍五入了]
mysql> select * from test1;
+----+-------------+---------+
| id | name | salary |
+----+-------------+---------+
| 1 | chenliang01 | 4000.00 |
| 2 | chenliang02 | 4000.23 |
| 3 | chenliang03 | 4000.24 |
+----+-------------+---------+
3 rows in set (0.00 sec)
-- 第二阶段验证数据
insert into test1(name,salary) values("chenliang04",300); -- 显示结果为300.00[因为你插入的值300位没有超过整数位的长度4(6-2),后面的小数会自动补全(因为你建表时指定了小数位是2位)
insert into test1(name,salary) values("chenliang05",300.234); -- 显示结果为300.23[你插入的值300.234总位数(整数位加小数位)未超过了6位,但小数位超过了指定的位数(2位),把以会把小数位给四舍五入了,为什么没有变成0300.23呢,是因为你没有加zerofill参数]
insert into test1(name,salary) values("chenliang06",300.236); -- 显示结果为300.24[你插入的值300.236总位数(整数位加小数位)未超过了6位,但小数位超过了指定的位数(2位),把以会把小数位给四舍五入了,为什么没有变成0300.24呢,是因为你没有加zerofill参数]
insert into test1(name,salary) values("chenliang07",30000); -- 直接报错(Out of range value for column 'salary' at row 1),因为你插入的值是整数30000,整数位超过了4位,直接报错
mysql> select * from test1 where id > 3;
+----+-------------+--------+
| id | name | salary |
+----+-------------+--------+
| 4 | chenliang04 | 300.00 |
| 5 | chenliang05 | 300.23 |
| 6 | chenliang06 | 300.24 |
+----+-------------+--------+
3 rows in set (0.00 sec)
-- 总结:
01:当所在列的类型为decimal类型时,且指定了范围,例如:decimal(6,2),加了unsigned参数,但没有加zerofill参数时:
02:你插入的值的长度(整数位加小数位)不能超过6位(因为你前面指定了总长度为6位)
03:你插入的值若是整数(就是没有小数),整数位不能超过4位,因为6-2等于4是整数的长度,但是小数位会以00来表示
04:你插入的值若是整数(没有小数,且长度没有达到4位),那么对于整数位不会前导0填充,因为你没有加zerofill参数
05:你插入的值的长度(整数位没有超过4位,但小数位超过了2位),那么会对小数位进行四舍5入
06:你插入的值的长度(只是整数,且整数位超过了4位),直接报Out of range value for column 'salary' at row 1错误
测试二创建test2表,salary列使用decimal类型,指定长度(6,2),指定zerofill参数(会把unsigned参数也带上,且对整数位进行前导师0填充)
-- 创建test2表
mysql> create table if not exists test2(
-> id int(10) unsigned not null auto_increment primary key comment"序列号",
-> name varchar(20) not null comment"姓名",
-> salary decimal(6,2) zerofill not null comment"工资" -- 注意:类型为decimal,范围为(6,2),加了zerofill参数(会把unsigned参数也带上)
-> )engine=innodb character set utf8 collate utf8_general_ci;
Query OK, 0 rows affected (0.00 sec)
-- 查看test2表的表结构
mysql> desc test2;
+--------+--------------------------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+--------+--------------------------------+------+-----+---------+----------------+
| id | int(10) unsigned | NO | PRI | NULL | auto_increment |
| name | varchar(20) | NO | | NULL | |
| salary | decimal(6,2) unsigned zerofill | NO | | NULL | |
+--------+--------------------------------+------+-----+---------+----------------+
3 rows in set (0.00 sec)
-- 测试数据
insert into test2(name,salary) values("chenliang01",300); -- 显示结果为0300.00[插入成功,因为整数位没有超过4位,300之所以会成0300是因为建表时加了zerofill参数,0300.00中的小数位00是因为你指定了小数位长度为2]
insert into test2(name,salary) values("chenliang02",300.2); -- 显示结果为0300.20[插入成功,因为值的长度(整数位加小数位没有超过6位),300之所以会成0300是因为建表时加了zerofill参数,0300.20中的小数位20是因为你指定了小数位长度为2]
mysql> select * from test2;
+----+-------------+---------+
| id | name | salary |
+----+-------------+---------+
| 1 | chenliang01 | 0300.00 |
| 2 | chenliang02 | 0300.20 |
+----+-------------+---------+
2 rows in set (0.00 sec)
-- 总结:
01:当所在列的类型为decimal类型时,且指定了范围,例如:decimal(6,2),且加了zerofill参数(会进行前导师0填充)
02:当你的插入的值(整数位不够4位(6-2))时,会对整数位进行前导师0填充,这是zerofill参数控制的
03:当你的插入的值(整数位没有超过4位,小数位没有达到2位),会在小数位后面加0,这是你建表时指定小数位长度所决定的