MySQL小数数据类型

第1章 小数类型和测试环境说明

1.1 小数数据类型有哪些

从官方网站上看

https://dev.mysql.com/doc/refman/5.7/en/numeric-types.html

1

自己整理的

类型说明格式占用存储(字节bytes)
float近似值(浮点)小数数据类型,小数位只能精确到7位float(M,D) unsigned zerofill
# M最大255位,含小数30位
# D最大30位
4
double近似值(浮点)小数数据类型,小数位只能精确到15位double(M,D) unsigned zerofill
# M最大255位,含小数30位
# D最大30位
8
decimal准确值(定点)小数数据类型,小数位完全精确decimal(M,D) unsigned zerofill
# M最大65位,含小数30位
# D最大30位
每个小数位占用1个字节
numeric准确值(定点)小数数据类型,小数位完全精确numeric(M,D) unsigned zerofill
# M最大65位,含小数30位
# D最大30位
每个小数位占用1个字节

PS:decimal和numeric是一样的,只不过名字不一样,官方的说法:在MySQL中,NUMERIC实现为DECIMAL

1.2 实践环境基本的说明

##### 数据库版本和默认的存储引擎
mysql> select @@version,@@default_storage_engine;
+------------+--------------------------+
| @@version  | @@default_storage_engine |
+------------+--------------------------+
| 5.7.28-log | InnoDB                   |
+------------+--------------------------+
1 row in set (0.00 sec)
 

##### 事务的提交方式是自动的(主要是针对DML语句)
mysql> select @@autocommit,@@global.autocommit;
+--------------+---------------------+
| @@autocommit | @@global.autocommit |
+--------------+---------------------+
|            1 |                   1 |
+--------------+---------------------+
1 row in set (0.00 sec)


##### 创建chenliang库,并进入到chenliang库下面
mysql> create database if not exists chenliang character set utf8 collate utf8_general_ci;
Query OK, 1 row affected (0.03 sec)
 
mysql> use chenliang;
Database changed
 
mysql> select database();
+------------+
| database() |
+------------+
| chenliang  |
+------------+
1 row in set (0.01 sec)


第2章 小数数据类型float

2.1 float的总结性说明

##### 格式
id        float(M,D)            unsigned                zerofill
字段名     数据类型(要指定M和D)     无符号(只针对整数位)       无符号(只针对整数位,但整数位不会前导零填充显示)


##### float的M和D说明和示例
M:表示"整数位""小数位"共多少位,M最大255位(包含小数位在内,小数30位);所以整数位最大长度是225;
D:表示"小数位"最大多少位,最大30位;
示例1:float(255,30)   # 整数位最大长度225位,小数位最大长度30位;
示例2:float(50,20)    # 整数位最大长度30位,小数位最大长度20位;


##### float数据类型默认的小数位精确度(只能精确到第7位)
字段定义:f float(255,30)   # 没有加unsigned和zerofill是因为它们都是针对整数位,而这里讨论的是小数位,跟他们没关系
插入数据:insert into test12(f) values(1.555555555555555555555555555555);
插入说明:往test12表中的f字段插入的数据是(整数位是1,小数位是30个5)
显示结果:1.555555582046508800000000000000
结果说明:可以看出小数位到第8位就不准确了(小数位只准确到了第7位)


##### 关于小数位的说明
01:若插入数据的小数位长度没有达到指定的小数位长度,则会在小数后面用零填充显示(跟zerofill无关哈);
02:若插入数据的小数位长度刚好达到指定的小数位长度,则不会用零填充,也不会四舍五入;
03:若插入数据的小数位长度已经超过指定的小数位长度,则会进行四舍五入;


##### 生产环境下当字段指定的数据类型为 float(5,2) 的举例说明
-- 加了unsigned属性
	A:sql_mode开启了严格模式(sql_mode包含strict_trans_tables)
	   插入1751.2    # 直接报错,因为开了严格模式,且指定的整数位最大长度是3
	   插入-175.2    # 直接报错,因为开了严格模式,且加了unsigned属性(无符号,针对整数位),
	   插入17.2      # 成功,整数位长度没超过指定长度3,显示的数据是17.20(小数位不够2位)
	   插入17.245    # 成功,整数位长度没超过指定长度3,显示的是17.25(小数位超过长度,四舍五入)
	
	B:sql_mode未开启严格模式(sql_mode不包含strict_trans_tables)
	   插入1751.2    # 成功且警告,虽然整数位超过了指定长度,但未开严格模式,到表中的数据是 999.99
	   插入-175.2    # 成功且警告,虽然加了unsigned属性(针对整数位),但未开严格模式,到表中数据是 0.00
	   插入17.2      # 成功,整数位长度没超过指定长度3,显示的数据是17.20(小数位不够2位)
	   插入17.245    # 成功,整数位长度没超过指定长度3,显示的是17.25(小数位超过长度,四舍五入)


-- 加了zerofill属性
	A:sql_mode开启了严格模式(sql_mode包含strict_trans_tables)
	   插入1751.2    # 直接报错,因为开了严格模式,且指定的整数位最大长度是3
	   插入-175.2    # 直接报错,因为开了严格模式,且加了zerofill属性(无符号,针对整数位),
	   插入17.2      # 成功,整数位长度没超过指定长度3,显示的数据是17.20(小数位不够2位)
	   插入17.245    # 成功,整数位长度没超过指定长度3,显示的是17.25(小数位超过长度,四舍五入)
	
	B:sql_mode未开启严格模式(sql_mode不包含strict_trans_tables)
	   插入1751.2    # 成功且警告,虽然整数位超过了指定长度,但未开严格模式,到表中的数据是 999.99
	   插入-175.2    # 成功且警告,虽然加了unsigned属性(针对整数位),但未开严格模式,到表中数据是 00.00
	   插入17.2      # 成功,整数位长度没超过指定长度3,显示的数据是17.20(小数位不够2位)
	   插入17.245    # 成功,整数位长度没超过指定长度3,显示的是17.25(小数位超过长度,四舍五入)


-- 没有加unsigned/zerofill属性
	A:sql_mode开启了严格模式(sql_mode包含strict_trans_tables)
	   插入1751.2    # 直接报错,因为开了严格模式,且指定的整数位最大长度是3;
	   插入-175.2    # 成功,因为没加unsigned或zerofill属性,且整数位没超过长度;
	   插入17.2      # 成功,整数位长度没超过指定长度3,显示的数据是17.20(小数位不够2位)
	   插入17.245    # 成功,整数位长度没超过指定长度3,显示的是17.25(小数位超过长度,四舍五入)
	
	B:sql_mode未开启严格模式(sql_mode不包含strict_trans_tables)
	   插入1751.2    # 成功且警告,虽然整数位超过了指定长度,但未开严格模式,到表中的数据是999.99
	   插入-175.2    # 成功,因为没加unsigned或zerofill属性,且整数位没超过长度
	   插入17.2      # 成功,整数位长度没超过指定长度3,显示的数据是17.20(小数位不够2位)
	   插入17.245    # 成功,整数位长度没超过指定长度3,显示的是17.25(小数位超过长度,四舍五入)

2.2 float数据类型小数位的默认精确度

总结

字段定义:f float(255,30)   # 没有加unsigned和zerofill是因为它们都是针对整数位,而这里讨论的是小数位,跟他们没关系
插入数据:insert into test12(f) values(1.555555555555555555555555555555);
插入说明:往test12表中的f字段插入的数据是(整数位是1,小数位是30个5)
显示结果:1.555555582046508800000000000000
结果说明:可以看出小数位到第8位就不准确了(小数位只准确到了第7位)

实践

#### 创建test22表
create table if not exists test22(
	f float(255,30)
)engine=innodb character set utf8 collate utf8_general_ci;

    # f字段没有加unsigned和zerofill属性,因为我们讨论的是float的精确度
    # 整数位的最大长度是255,小数位的最大长度是30

#### 查看tst22表的表结构
mysql> desc test22;
+-------+---------------+------+-----+---------+-------+
| Field | Type          | Null | Key | Default | Extra |
+-------+---------------+------+-----+---------+-------+
| f     | float(255,30) | YES  |     | NULL    |       |
+-------+---------------+------+-----+---------+-------+
1 row in set (0.00 sec)


#### 插入测试数据
mysql> insert into test22(f) values(1.555555555555555555555555555555);
Query OK, 1 row affected (0.01 sec)

mysql> select * from test22;
+----------------------------------+
| f                                |
+----------------------------------+
| 1.555555582046508800000000000000 |
+----------------------------------+
1 row in set (0.00 sec)

2.3 测试unsigned属性

注意:unsigned表示无符号,它只针对数值的整数位

sql_mode开启了严格模式,即sql_mode参数中包含strict_trans_tables变量

#### 设置当前会话模式下,sql_mode开启严格模式,DML语句自动提交
set session autocommit=on;
set session sql_mode="strict_trans_tables";


#### 创建test23_1表,并查看表的表结构
create table if not exists test23_1(
	f float(5,2) unsigned
)engine=innodb character set utf8 collate utf8_general_ci;

   # f字段整数位的最大长度是3,小数位的最大长度是2;
   # 加了unsigned属性,那么整数位只能是正整数;
   # 若插入数据的小数位长度没有达到指定的小数位长度,则会在小数后面用零填充显示;
   # 若插入数据的小数位长度刚好达到指定的小数位长度,则不会用零填充,也不会四舍五入;
   # 若插入数据的小数位长度已经超过指定的小数位长度,则会进行四舍五入;
   
mysql> desc test23_1;
+-------+---------------------+------+-----+---------+-------+
| Field | Type                | Null | Key | Default | Extra |
+-------+---------------------+------+-----+---------+-------+
| f     | float(5,2) unsigned | YES  |     | NULL    |       |
+-------+---------------------+------+-----+---------+-------+
1 row in set (0.00 sec)


#### 插入数据进行测试
insert into test23_1(f) values(1751.2);
		# 直接报错,因为插入数值的整数位超过了指定的长度3位,且开启了严格模式
		# 数据不会到达表中

insert into test23_1(f) values(-175.2);
		# 直接报错,因为加了unsigned,整数位只能是正整数,且sql_mode开启了严格模式,
		# 数据不会到达表中

insert into test23_1(f) values(17.2);
        # 成功,插入到表中的数据是17.2,显示的时候是17.20,因为小数位长度不够2位,
        # 会在后面用零填充显示;

insert into test23_1(f) values(17.245);
        # 成功,到表中的数据不是17.245,因为小数位超过指定的长度2了,会进行四舍五入
        # 最后到表中的数据是17.25,显示的时候也是17.25

mysql> select * from test23_1;
+--------+
| f      |
+--------+
| 17.20  |
| 17.25  |
+--------+
2 rows in set (0.00 sec)

sql_mode未开启严格模式,即sql_mode参数中不包含strict_trans_tables变量

#### 设置当前会话模式下,sql_mode未开启严格模式,DML语句自动提交
set session autocommit=on;
set session sql_mode="";


#### 创建test23_2表,并查看表的表结构
create table if not exists test23_2(
	f float(5,2) unsigned
)engine=innodb character set utf8 collate utf8_general_ci;

   # f字段整数位的最大长度是3,小数位的最大长度是2
   # 加了unsigned属性,那么整数位只能是正整数
   # 若插入数据的小数位长度没有达到指定的小数位长度,则会在小数后面用零填充显示
   # 若插入数据的小数位长度刚好达到指定的小数位长度,则不会用零填充,也不会四舍五入
   # 若插入数据的小数位长度已经超过指定的小数位长度,则会进行四舍五入;
   
mysql> desc test23_2;
+-------+---------------------+------+-----+---------+-------+
| Field | Type                | Null | Key | Default | Extra |
+-------+---------------------+------+-----+---------+-------+
| f     | float(5,2) unsigned | YES  |     | NULL    |       |
+-------+---------------------+------+-----+---------+-------+
1 row in set (0.01 sec)


#### 插入数据进行测试
insert into test23_2(f) values(1751.2);
		# 成功且有警告,按理说,整数位已经超过指定的长度3了,但sql_mode未开严格模式
		# 数据会到达表中,到表中的数据是999.99

insert into test23_2(f) values(-175.2);
		# 成功且有警告,按理说,整数位应该是正整数,因为字段加了unsigned属性,但示开严格模
		# 式,数据会到达表,到表中的数据是0.00

insert into test23_2(f) values(17.2);
        # 成功,插入到表中的数据是175.2,显示的时候是175.20,因为小数位长度不够2位,
        # 会在后面用零填充显示;

insert into test23_2(f) values(17.245);
        # 成功,到表中的数据不是17.245,因为小数位超过指定的长度2了,会进行四舍五入
        # 最后到表中的数据是17.25,显示的时候也是17.25

mysql> select * from test23_2;
+--------+
| f      |
+--------+
| 999.99 |
|   0.00 |
| 17.20  |
| 17.25  |
+--------+
4 rows in set (0.00 sec)

2.4 测试zerofill属性

注意:zerofill表示无符号,因为它包含unsigned属性,针对整数位,但不会进行前导0填充

sql_mode开启了严格模式,即sql_mode参数中包含strict_trans_tables变量

#### 设置当前会话模式下,sql_mode开启严格模式,DML语句自动提交
set session autocommit=on;
set session sql_mode="strict_trans_tables";


#### 创建test24_1表,并查看表的表结构
create table if not exists test24_1(
	f float(5,2) zerofill
)engine=innodb character set utf8 collate utf8_general_ci;

   # f字段整数位的最大长度是3,小数位的最大长度是2
   # 加了zerofill属性,那么整数位只能是正整数(且显示时会前导师零填充显示)
   # 若插入数据的小数位长度没有达到指定的小数位长度,则会在小数后面用零填充显示
   # 若插入数据的小数位长度刚好达到指定的小数位长度,则不会用零填充,也不会四舍五入
   # 若插入数据的小数位长度已经超过指定的小数位长度,则会进行四舍五入;
   
mysql> desc test24_1;
+-------+------------------------------+------+-----+---------+-------+
| Field | Type                         | Null | Key | Default | Extra |
+-------+------------------------------+------+-----+---------+-------+
| f     | float(5,2) unsigned zerofill | YES  |     | NULL    |       |
+-------+------------------------------+------+-----+---------+-------+
1 row in set (0.00 sec)


#### 插入数据进行测试
insert into test24_1(f) values(1751.2);
		# 直接报错,因为插入的数值的整数位超过了指定的长度3位,且sql_mode开启了严格模式,数据不会到达表中

insert into test24_1(f) values(-175.2);
		# 直接报错,因为加了zerofill,整数位只能是正整数,且sql_mode开启了严格模式,数据不会到达表中

insert into test24_1(f) values(17.2);
		# 成功,数据会到达表中,到表中的数据是17.2,最终显示的数据是17.20
		# 整数位不够长度,不会前导0填充显示,即使加了zerofill属性
		# 小数位不够长度,会后导0填充显示,这个和zerofill属性无关

insert into test24_1(f) values(17.245);
		# 成功,到表中的数据是17.25,显示的时候是17.25
		# 整数位不够长度,不会前导0填充显示,即使加了zerofill属性
		# 小数位超过长度,会四舍五入

mysql> select * from test24_1;
+-------+
| f     |
+-------+
| 17.20 |
| 17.25 |
+-------+
2 rows in set (0.00 sec)

sql_mode未开启严格模式,即sql_mode参数中不包含strict_trans_tables变量

#### 设置当前会话模式下,sql_mode未开启严格模式,DML语句自动提交
set session autocommit=on;
set session sql_mode="";


#### 创建test24_2表,并查看表的表结构
create table if not exists test24_2(
	f float(5,2) zerofill
)engine=innodb character set utf8 collate utf8_general_ci;

   # f字段整数位的最大长度是3,小数位的最大长度是2
   # 加了zerofill属性,那么整数位只能是正整数(且显示时会前导师零填充显示)
   # 若插入数据的小数位长度没有达到指定的小数位长度,则会在小数后面用零填充显示
   # 若插入数据的小数位长度刚好达到指定的小数位长度,则不会用零填充,也不会四舍五入
   # 若插入数据的小数位长度已经超过指定的小数位长度,则会进行四舍五入;
   
mysql> desc test24_2;
+-------+------------------------------+------+-----+---------+-------+
| Field | Type                         | Null | Key | Default | Extra |
+-------+------------------------------+------+-----+---------+-------+
| f     | float(5,2) unsigned zerofill | YES  |     | NULL    |       |
+-------+-------------------------------------------------------------+

#### 插入数据进行测试
insert into test24_2(f) values(1751.2);
		# 成功且有警告,虽然整数位超过了指定长度3,但sql_mode未开严格模式
		# 所以到表中的数据是999.99

insert into test24_2(f) values(-175.2);
		# 成都且有警告,虽然整数位不能是负整数,但sql_mode未开严格模式
		# 所以到表中的数据是00.00

insert into test24_2(f) values(17.2);
		# 成功,数据会到达表中,到表中的数据是17.2,最终显示的数据是17.20
		# 整数位不够长度,不会前导0填充显示,即使加了zerofill属性
		# 小数位不够长度,会后导0填充显示,这个和zerofill属性无关

insert into test24_2(f) values(17.245);
		# 成功,到表中的数据是17.25,显示的时候是17.25
		# 整数位不够长度,不会前导0填充显示,即使加了zerofill属性;
		# 小数位超过长度,会四舍五入;

mysql> select * from test24_2;
+--------+
| f      |
+--------+
| 999.99 |
|  00.00 |
|  17.20 |
|  17.25 |
+--------+
4 rows in set (0.00 sec)

2.5 测试不加unsigned/zerofill属性

注意:不加unsigned和zerofill属性,这样数值的整数位就可以是正整数或者负整数了

sql_mode开启了严格模式,即sql_mode参数中包含strict_trans_tables变量

#### 设置当前会话模式下,sql_mode开启严格模式,DML语句自动提交
set session autocommit=on;
set session sql_mode="strict_trans_tables";


#### 创建test25_1表,并查看其表结构
create table if not exists test25_1(
  f float(5,2)
)engine=innodb character set utf8 collate utf8_general_ci;

   # f字段整数位的最大长度是3,小数位的最大长度是2;
   # 没有加unsigned/zerofill属性,那么整数位可以是正整数和负整数
   # 若插入数据的小数位长度没有达到指定的小数位长度,则会在小数后面用零填充显示;
   # 若插入数据的小数位长度刚好达到指定的小数位长度,则不会用零填充,也不会四舍五入;
   # 若插入数据的小数位长度已经超过指定的小数位长度,则会进行四舍五入;

mysql> desc test25_1;
+-------+------------+------+-----+---------+-------+
| Field | Type       | Null | Key | Default | Extra |
+-------+------------+------+-----+---------+-------+
| f     | float(5,2) | YES  |     | NULL    |       |
+-------+------------+------+-----+---------+-------+
1 row in set (0.00 sec)


#### 插入测试数据进行测试
insert into test25_1(f) values(1751.2);
		# 直接报错,因为插入数值的整数位超过了指定的长度3位,且开启了严格模式
		# 数据不会到达表中

insert into test25_1(f) values(-175.2);
		# 成功,因为没加unsigned/zerofill,整数位可以是负正整数,数据会到达表中

insert into test25_1(f) values(17.2);
        # 成功,插入到表中的数据是17.2,显示的时候是17.20,因为小数位长度不够2位,
        # 会在后面用零填充显示;

insert into test25_1(f) values(17.245);
        # 成功,到表中的数据不是17.245,因为小数位超过指定的长度2了,会进行四舍五入
        # 最后到表中的数据是17.25,显示的时候也是17.25

mysql> select * from test25_1;
+---------+
| f       |
+---------+
| -175.20 |
|   17.20 |
|   17.25 |
+---------+
3 rows in set (0.00 sec)

sql_mode未开启严格模式,即sql_mode参数中不包含strict_trans_tables变量

#### 设置当前会话模式下,sql_mode未开启严格模式,DML语句自动提交
set session autocommit=on;
set session sql_mode="";


#### 创建test26_2表,并查看其表结构
create table if not exists test25_2(
  f float(5,2)
)engine=innodb character set utf8 collate utf8_general_ci;

   # f字段整数位的最大长度是3,小数位的最大长度是2;
   # 没有加unsigned/zerofill属性,那么整数位可以是正整数和负整数
   # 若插入数据的小数位长度没有达到指定的小数位长度,则会在小数后面用零填充显示;
   # 若插入数据的小数位长度刚好达到指定的小数位长度,则不会用零填充,也不会四舍五入;
   # 若插入数据的小数位长度已经超过指定的小数位长度,则会进行四舍五入;

mysql> desc test25_2;
+-------+------------+------+-----+---------+-------+
| Field | Type       | Null | Key | Default | Extra |
+-------+------------+------+-----+---------+-------+
| f     | float(5,2) | YES  |     | NULL    |       |
+-------+------------+------+-----+---------+-------+
1 row in set (0.00 sec)


#### 插入测试数据进行测试
insert into test25_2(f) values(1751.2);
		# 成功且警告,整数位超过长度3,但未开启严格模式;数据到表中是999.99

insert into test25_2(f) values(-175.2);
		# 成功,因为没加unsigned/zerofill,整数位可以是负正整数,数据会到达表中;

insert into test25_2(f) values(17.2);
        # 成功,插入到表中的数据是17.2,显示的时候是17.20,因为小数位长度不够2位,
        # 会在后面用零填充显示;

insert into test25_2(f) values(17.245);
        # 成功,到表中的数据不是17.245,因为小数位超过指定的长度2了,会进行四舍五入
        # 最后到表中的数据是17.25,显示的时候也是17.25

mysql> select * from test25_2;
+---------+
| f       |
+---------+
|  999.99 |
| -175.20 |
|   17.20 |
|   17.25 |
+---------+
4 rows in set (0.00 sec)


第3章 小数数据类型double

3.1 double的总结性说明

## 格式
id      double(M,D)         unsigned            zerofill
字段名    数据类型(要指定M和D)    无符号(只针对整数位)    无符号(只针对整数位,但整数位不会前导零填充显示)


## double的M和D说明和示例
M:表示"整数位""小数位"共多少位,M最大255位(包含小数位在内,小数30位);所以整数位最大长度是225;
D:表示"小数位"最大多少位,最大30位;
示例1:double(255,30)   # 整数位最大长度225位,小数位最大长度30位;
示例2:double(50,20)    # 整数位最大长度30位,小数位最大长度20位;


## 关于小数位的说明
01:若插入数据的小数位长度没有达到指定的小数位长度,则会在小数后面用零填充显示(跟zerofill无关哈);
02:若插入数据的小数位长度刚好达到指定的小数位长度,则不会用零填充,也不会四舍五入;
03:若插入数据的小数位长度已经超过指定的小数位长度,则会进行四舍五入;


## 关于double数据类型小数位的精确度说明
字段定义:d double(255,30)  # 整数位最大长度225位,小数位最大长度30位
定义说明:没加unsigned和zerofill是因它们都是针对整数位,而这里讨论的是小数位,跟他们没关系 
插入数据:insert into test12(d) values(1.555555555555555555555555555555);
插入说明:往test12表中的d字段插入的数据是(整数位是1,小数位是30个5)
显示结果:1.555555555555555600000000000000
结果说明:可以看出小数位到第16位就不准确了(小数位只准确到了第16位)


## 生产环境下当字段指定的数据类型为 double(5,2) 的举例说明
-- 加了unsigned属性
	A:sql_mode开启了严格模式(sql_mode包含strict_trans_tables)
	   插入1751.2    # 直接报错,因为开了严格模式,且指定的整数位最大长度是3
	   插入-175.2    # 直接报错,因为开了严格模式,且加了unsigned属性(无符号,针对整数位),
	   插入17.2      # 成功,整数位长度没超过指定长度3,显示的数据是17.20(小数位不够2位)
	   插入17.245    # 成功,整数位长度没超过指定长度3,显示的是17.25(小数位超过长度,四舍五入)
	
	B:sql_mode未开启严格模式(sql_mode不包含strict_trans_tables)
	  插入1751.2     # 成功且警告,虽然整数位超过了指定长度,但未开严格模式,到表中的数据是999.99
	   插入-175.2    # 成功且警告,虽然加了unsigned属性(针对整数位),但未开严格模式,到表中数据是0.00
	   插入17.2      # 成功,整数位长度没超过指定长度3,显示的数据是17.20(小数位不够2位)
	   插入17.245    # 成功,整数位长度没超过指定长度3,显示的是17.25(小数位超过长度,四舍五入)

-- 加了zerofill属性
	A:sql_mode开启了严格模式(sql_mode包含strict_trans_tables)
	   插入1751.2    # 直接报错,因为开了严格模式,且指定的整数位最大长度是3
	   插入-175.2    # 直接报错,因为开了严格模式,且加了zerofill属性(无符号,针对整数位),
	   插入17.2      # 成功,整数位长度没超过指定长度3,显示的数据是17.20(小数位不够2位)
	   插入17.245    # 成功,整数位长度没超过指定长度3,显示的是17.25(小数位超过长度,四舍五入)
	
	B:sql_mode未开启严格模式(sql_mode不包含strict_trans_tables)
	   插入1751.2    # 成功且警告,虽然整数位超过了指定长度,但未开严格模式,到表中的数据是999.99
	   插入-175.2    # 成功且警告,虽然加了unsigned属性(针对整数位),但未开严格模式,到表中数据是00.00
	   插入17.2      # 成功,整数位长度没超过指定长度3,显示的数据是17.20(小数位不够2位)
	   插入17.245    # 成功,整数位长度没超过指定长度3,显示的是17.25(小数位超过长度,四舍五入)

-- 没加unsigned/zerofill属性
	A:sql_mode开启了严格模式(sql_mode包含strict_trans_tables)
	   插入1751.2    # 直接报错,因为开了严格模式,且指定的整数位最大长度是3
	   插入-175.2    # 成功,因为没加unsigned或zerofill属性,且整数位没超过长度
	   插入17.2      # 成功,整数位长度没超过指定长度3,显示的数据是17.20(小数位不够2位)
	   插入17.245    # 成功,整数位长度没超过指定长度3,显示的是17.25(小数位超过长度,四舍五入)
	
	B:sql_mode未开启严格模式(sql_mode不包含strict_trans_tables)
	   插入1751.2    # 成功且警告,虽然整数位超过了指定长度,但未开严格模式,到表中的数据是999.99
	   插入-175.2    # 成功,因为没加unsigned或zerofill属性,且整数位没超过长度
	   插入17.2      # 成功,整数位长度没超过指定长度3,显示的数据是17.20(小数位不够2位)
	   插入17.245    # 成功,整数位长度没超过指定长度3,显示的是17.25(小数位超过长度,四舍五入)

3.2 double数据类型小数位的默认精确度

总结

字段定义:d double(255,30)  
插入数据:insert into test13(f) values(1.555555555555555555555555555555);
结果显示:1.555555555555555600000000000000
结果总结:可以看出小数位的第16位就不准确了,只准确到了第15位小数位;

实践

#### 创建test32表
create table if not exists test32(
	d double(255,30)
)engine=innodb character set utf8 collate utf8_general_ci;

	# f字段没有加unsigned和zerofill属性,因为我们讨论的是float的精确度
	# 整数位的最大长度是255,小数位的最大长度是30


#### 查看test32表的表结构
mysql> desc test32;
+-------+---------------+------+-----+---------+-------+
| Field | Type          | Null | Key | Default | Extra |
+-------+---------------+------+-----+---------+-------+
| d     | double(255,30)| YES  |     | NULL    |       |
+-------+---------------+------+-----+---------+-------+
1 row in set (0.00 sec)


#### 插入测试数据
mysql> insert into test32(d) values(1.555555555555555555555555555555);
Query OK, 1 row affected (0.01 sec)

mysql> select * from test32;
+----------------------------------+
| d                                |
+----------------------------------+
| 1.555555555555555600000000000000 |
+----------------------------------+
1 row in set (0.00 sec)

3.3 测试unsigned属性

注意:unsigned表示无符号,它只针对数值的整数位

sql_mode开启了严格模式,即sql_mode参数中包含strict_trans_tables变量

#### 设置当前会话模式下,sql_mode开启严格模式,DML语句自动提交
set session autocommit=on;
set session sql_mode="strict_trans_tables";


#### 创建test33_1表,并查看表的表结构
create table if not exists test33_1(
	d double(5,2) unsigned
)engine=innodb character set utf8 collate utf8_general_ci;

   # f字段整数位的最大长度是3,小数位的最大长度是2;
   # 加了unsigned属性,那么整数位只能是正整数;
   # 若插入数据的小数位长度没有达到指定的小数位长度,则会在小数后面用零填充显示;
   # 若插入数据的小数位长度刚好达到指定的小数位长度,则不会用零填充,也不会四舍五入;
   # 若插入数据的小数位长度已经超过指定的小数位长度,则会进行四舍五入;
   
mysql> desc test33_1;
+-------+---------------------+------+-----+---------+-------+
| Field | Type                | Null | Key | Default | Extra |
+-------+---------------------+------+-----+---------+-------+
| d     | double(5,2) unsigned| YES  |     | NULL    |       |
+-------+---------------------+------+-----+---------+-------+
1 row in set (0.00 sec)


#### 插入数据进行测试
insert into test33_1(d) values(1751.2);
		# 直接报错,因为插入数值的整数位超过了指定的长度3位,且开启了严格模式
		# 数据不会到达表中

insert into test33_1(d) values(-175.2);
		# 直接报错,因为加了unsigned,整数位只能是正整数,且sql_mode开启了严格模式,
		# 数据不会到达表中

insert into test33_1(d) values(17.2);
        # 成功,插入到表中的数据是17.2,显示的时候是17.20,因为小数位长度不够2位,
        # 会在后面用零填充显示;

insert into test33_1(d) values(17.245);
        # 成功,到表中的数据不是17.245,因为小数位超过指定的长度2了,会进行四舍五入
        # 最后到表中的数据是17.25,显示的时候也是17.25

mysql> select * from test33_1;
+--------+
| d      |
+--------+
| 17.20  |
| 17.25  |
+--------+
2 rows in set (0.00 sec)

sql_mode未开启严格模式,即sql_mode参数中不包含strict_trans_tables变量

#### 设置当前会话模式下,sql_mode未开启严格模式,DML语句自动提交
set session autocommit=on;
set session sql_mode="";


#### 创建test33_2表,并查看表的表结构
create table if not exists test33_2(
	d double(5,2) unsigned
)engine=innodb character set utf8 collate utf8_general_ci;

   # f字段整数位的最大长度是3,小数位的最大长度是2
   # 加了unsigned属性,那么整数位只能是正整数
   # 若插入数据的小数位长度没有达到指定的小数位长度,则会在小数后面用零填充显示
   # 若插入数据的小数位长度刚好达到指定的小数位长度,则不会用零填充,也不会四舍五入
   # 若插入数据的小数位长度已经超过指定的小数位长度,则会进行四舍五入;
   
mysql> desc test33_2;
+-------+----------------------+------+-----+---------+-------+
| Field | Type                 | Null | Key | Default | Extra |
+-------+----------------------+------+-----+---------+-------+
| d     | double(5,2) unsigned | YES  |     | NULL    |       |
+-------+----------------------+------+-----+---------+-------+
1 row in set (0.01 sec)


#### 插入数据进行测试
insert into test33_2(d) values(1751.2);
		# 成功且有警告,按理说,整数位已经超过指定的长度3了,但sql_mode未开严格模式
		# 数据会到达表中,到表中的数据是999.99

insert into test33_2(d) values(-175.2);
		# 成功且有警告,按理说,整数位应该是正整数,因为字段加了unsigned属性,但示开严格模
		# 式,数据会到达表,到表中的数据是0.00

insert into test33_2(d) values(17.2);
        # 成功,插入到表中的数据是175.2,显示的时候是175.20,因为小数位长度不够2位,
        # 会在后面用零填充显示;

insert into test33_2(d) values(17.245);
        # 成功,到表中的数据不是17.245,因为小数位超过指定的长度2了,会进行四舍五入
        # 最后到表中的数据是17.25,显示的时候也是17.25

mysql> select * from test33_2;
+--------+
| d      |
+--------+
| 999.99 |
|   0.00 |
| 17.20  |
| 17.25  |
+--------+
4 rows in set (0.00 sec)

3.4 测试zerofill属性

注意:zerofill表示无符号,因为它包含unsigned属性,针对整数位,但不会进行前导0填充

sql_mode开启了严格模式,即sql_mode参数中包含strict_trans_tables变量

#### 设置当前会话模式下,sql_mode开启严格模式,DML语句自动提交
set session autocommit=on;
set session sql_mode="strict_trans_tables";


#### 创建test34_1表,并查看表的表结构
create table if not exists test34_1(
	d double(5,2) zerofill
)engine=innodb character set utf8 collate utf8_general_ci;

   # f字段整数位的最大长度是3,小数位的最大长度是2
   # 加了zerofill属性,那么整数位只能是正整数(且显示时会前导师零填充显示)
   # 若插入数据的小数位长度没有达到指定的小数位长度,则会在小数后面用零填充显示
   # 若插入数据的小数位长度刚好达到指定的小数位长度,则不会用零填充,也不会四舍五入
   # 若插入数据的小数位长度已经超过指定的小数位长度,则会进行四舍五入;

mysql> desc test34_1;
+-------+-------------------------------+------+-----+---------+-------+
| Field | Type                          | Null | Key | Default | Extra |
+-------+-------------------------------+------+-----+---------+-------+
| d     | double(5,2) unsigned zerofill | YES  |     | NULL    |       |
+-------+-------------------------------+------+-----+---------+-------+
1 row in set (0.00 sec)


#### 插入数据进行测试
insert into test34_1(d) values(1751.2);
		# 直接报错,因为插入的数值的整数位超过了指定的长度3位,数据不会到达表中

insert into test34_1(d) values(-175.2);
		# 直接报错,因为加了zerofill,整数位只能是正整数,且sql_mode开启了严格模式,
		# 数据不会到达表中

insert into test34_1(d) values(17.2);
		# 成功,数据会到达表中,到表中的数据是17.2,最终显示的数据是17.20
		# 整数位不够长度,不会前导0填充显示,即使加了zerofill属性
		# 小数位不够长度,会后导0填充显示,这个和zerofill属性无关

insert into test34_1(d) values(17.245);
		# 成功,到表中的数据是17.25,显示的时候是17.25
		# 整数位不够长度,不会前导0填充显示,即使加了zerofill属性
		# 小数位超过长度,会四舍五入

mysql> select * from test34_1;
+-------+
| d     |
+-------+
| 17.20 |
| 17.25 |
+-------+
2 rows in set (0.00 sec)

sql_mode未开启严格模式,即sql_mode参数中不包含strict_trans_tables变量

#### 设置当前会话模式下,sql_mode未开启严格模式,DML语句自动提交
set session autocommit=on;
set session sql_mode="";


#### 创建test34_2表,并查看表的表结构
create table if not exists test34_2(
	d double(5,2) zerofill
)engine=innodb character set utf8 collate utf8_general_ci;
  
   # f字段整数位的最大长度是3,小数位的最大长度是2
   # 加了zerofill属性,那么整数位只能是正整数(且显示时会前导师零填充显示)
   # 若插入数据的小数位长度没有达到指定的小数位长度,则会在小数后面用零填充显示
   # 若插入数据的小数位长度刚好达到指定的小数位长度,则不会用零填充,也不会四舍五入
   # 若插入数据的小数位长度已经超过指定的小数位长度,则会进行四舍五入;
   
mysql> desc test34_2;
+-------+------------------------------ +------+-----+---------+-------+
| Field | Type                          | Null | Key | Default | Extra |
+-------+-------------------------------+------+-----+---------+-------+
| d     | double(5,2) unsigned zerofill | YES  |     | NULL    |       |
+-------+-------------------------------+------+-----+---------+-------+

#### 插入数据进行测试
insert into test34_2(d) values(1751.2);
		# 成功且有警告,虽然整数位超过了指定长度3,但sql_mode未开严格模式
		# 所以到表中的数据是999.99

insert into test34_2(d) values(-175.2);
		# 成都且有警告,虽然整数位不能是负整数,但sql_mode未开严格模式
		# 所以到表中的数据是00.00

insert into test34_2(d) values(17.2);
		# 成功,数据会到达表中,到表中的数据是17.2,最终显示的数据是17.20
		# 整数位不够长度,不会前导0填充显示,即使加了zerofill属性
		# 小数位不够长度,会后导0填充显示,这个和zerofill属性无关

insert into test34_2(d) values(17.245);
		# 成功,到表中的数据是17.25,显示的时候是17.25
		# 整数位不够长度,不会前导0填充显示,即使加了zerofill属性;
		# 小数位超过长度,会四舍五入;

mysql> select * from test34_2;
+--------+
| d      |
+--------+
| 999.99 |
|  00.00 |
|  17.20 |
|  17.25 |
+--------+
4 rows in set (0.00 sec)

3.5 测试不加unsigned/zerofill属性

注意:不加unsigned和zerofill属性,这样数值的整数位就可以是正整数或者负整数了

sql_mode开启了严格模式,即sql_mode参数中包含strict_trans_tables变量

#### 设置当前会话模式下,sql_mode开启严格模式,DML语句自动提交
set session autocommit=on;
set session sql_mode="strict_trans_tables";


#### 创建test35_1表,并查看其表结构
create table if not exists test35_1(
  d double(5,2)
)engine=innodb character set utf8 collate utf8_general_ci;

   # f字段整数位的最大长度是3,小数位的最大长度是2;
   # 没有加unsigned/zerofill属性,那么整数位可以是正整数和负整数
   # 若插入数据的小数位长度没有达到指定的小数位长度,则会在小数后面用零填充显示;
   # 若插入数据的小数位长度刚好达到指定的小数位长度,则不会用零填充,也不会四舍五入;
   # 若插入数据的小数位长度已经超过指定的小数位长度,则会进行四舍五入;

mysql> desc test35_1;
+-------+-------------+------+-----+---------+-------+
| Field | Type        | Null | Key | Default | Extra |
+-------+-------------+------+-----+---------+-------+
| d     | double(5,2) | YES  |     | NULL    |       |
+-------+-------------+------+-----+---------+-------+
1 row in set (0.00 sec)


#### 插入测试数据进行测试
insert into test35_1(d) values(1751.2);
		# 直接报错,因为插入数值的整数位超过了指定的长度3位,且开启了严格模式
		# 数据不会到达表中

insert into test35_1(d) values(-175.2);
		# 成功,因为没加unsigned/zerofill,整数位可以是负正整数,数据会到达表中是-175.20

insert into test35_1(d) values(17.2);
        # 成功,插入到表中的数据是17.2,显示的时候是17.20,因为小数位长度不够2位,
        # 会在后面用零填充显示;

insert into test35_1(d) values(17.245);
        # 成功,到表中的数据不是17.245,因为小数位超过指定的长度2了,会进行四舍五入
        # 最后到表中的数据是17.25,显示的时候也是17.25

mysql> select * from test35_1;
+---------+
| d       |
+---------+
| -175.20 |
|   17.20 |
|   17.25 |
+---------+
3 rows in set (0.00 sec)

sql_mode未开启严格模式,即sql_mode参数中不包含strict_trans_tables变量

#### 设置当前会话模式下,sql_mode未开启严格模式,DML语句自动提交
set session autocommit=on;
set session sql_mode="";


#### 创建test35_2表,并查看其表结构
create table if not exists test35_2(
  d double(5,2)
)engine=innodb character set utf8 collate utf8_general_ci;

   # f字段整数位的最大长度是3,小数位的最大长度是2;
   # 没有加unsigned/zerofill属性,那么整数位可以是正整数和负整数
   # 若插入数据的小数位长度没有达到指定的小数位长度,则会在小数后面用零填充显示;
   # 若插入数据的小数位长度刚好达到指定的小数位长度,则不会用零填充,也不会四舍五入;
   # 若插入数据的小数位长度已经超过指定的小数位长度,则会进行四舍五入;

mysql> desc test35_2;
+-------+-------------+------+-----+---------+-------+
| Field | Type        | Null | Key | Default | Extra |
+-------+-------------+------+-----+---------+-------+
| d     | double(5,2) | YES  |     | NULL    |       |
+-------+-------------+------+-----+---------+-------+
1 row in set (0.00 sec)


#### 插入测试数据进行测试
insert into test35_2(d) values(1751.2);
        # 成功且警告,整数位超过长度3,但未开启严格模式;数据到表中是999.99

insert into test35_2(d) values(-175.2);
		# 成功,因为没加unsigned/zerofill,整数位可以是负正整数,数据会到达表中,-175.20


insert into test35_2(d) values(17.2);
        # 成功,插入到表中的数据是17.2,显示的时候是17.20,因为小数位长度不够2位,
        # 会在后面用零填充显示;

insert into test35_2(d) values(17.245);
        # 成功,到表中的数据不是17.245,因为小数位超过指定的长度2了,会进行四舍五入
        # 最后到表中的数据是17.25,显示的时候也是17.25

mysql> select * from test35_2;
+---------+
| d       |
+---------+
|  999.99 |
| -175.20 |
|   17.20 |
|   17.25 |
+---------+
4 rows in set (0.00 sec)


第4章 小数数据类型decimal

4.1 decimal的总结性说明

注意:numeric只是decimal的一个同意词

#### 格式
id    decimal(M,D)      unsigned            zerofill
字段名  数据类型(要指定的哈)   无符号(只针对整数位)   无符号(包含unsigned,只针对整数位,会前导0填充)


#### decimal的M和D的最大值说明和示例
M:"整数位""小数位"共多少位,最大65位(含小数在内,小数30位);所以整数位最大长度是35;
D:表示"小数位"最大多少位,最大30位;
示例1:decimal(65,30)    # 整数位最大长度35位,小数位最大长度30位;
示例2:decimal(50,20)    # 整数位最大长度30位,小数位最大长度20位;


#### 关于小数位的说明
01:若插入数据的小数位长度没有达到指定的小数位长度,则会在小数后面用零填充显示(跟zerofill无关哈);
02:若插入数据的小数位长度刚好达到指定的小数位长度,则不会用零填充,也不会四舍五入;
03:若插入数据的小数位长度已经超过指定的小数位长度,则会进行四舍五入;


#### 关于decimal数据类型小数位的精确度说明
字段定义:decimal(65,30)  # 整数位最大长度35位,小数位最大长度30位
定义说明:没加unsigned和zerofill是因它们都是针对整数位,而这里讨论的是小数位,跟他们没关系
插入数据:insert into test12(d) values(1.555555555555555555555555555555);
插入说明:往test12表中的d字段插入的数据是(整数位是1,小数位是30个5)
显示结果:1.555555555555555555555555555555  <== 小数位精确度到了30位


#### 生产环境下当字段指定的数据类型为 decimal(5,2) 的举例说明
-- 加了unsigned属性
	A:sql_mode开启了严格模式(sql_mode包含strict_trans_tables)
	   插入1751.2   # 直接报错,因开了严格模式,且整数位超过指定的最大长度3
	   插入-175.2   # 直接报错,因开了严格模式,且加了unsigned属性
	   插入17.2     # 成功,整数位长度没超过指定长度3,显示的数据是17.20(小数位不够2位)
	   插入17.245   # 成功,整数位长度没超过指定长度3,小数位超过长度会四舍五入,结果:17.25
	
	B:sql_mode未开启严格模式(sql_mode不包含strict_trans_tables)
	   插入1751.2   # 成功且警告,虽然整数位超过了指定长度,但未开严格模式,到表中的数据是999.99
	   插入-175.2   # 成功且警告,虽然加了unsigned属性(针对整数位),但未开严格模式,到表中数据是0.00
	   插入17.2     # 成功,整数位长度没超过指定长度3,小数位不够长度,用0填充,最终结果:17.20
	   插入17.245   # 成功,整数位长度没超过指定长度3,小数位超过长度,四舍五入,最终结果:17.25


-- 加了zerofill属性
	A:sql_mode开启了严格模式(sql_mode包含strict_trans_tables)
	   插入1751.2    # 直接报错,因开了严格模式,且整数位超过指定的最大长度是3
	   插入-175.2    # 直接报错,因为开了严格模式,且加了zerofill属性,整数位只能插入正整数;
	   插入17.2      # 成功,整数位长度没超过指定长度3,小数位长度不够,用0填充,结果:017.20
	   插入17.245    # 成功,整数位长度没超过指定长度3,小数位长度超过,四舍五入,结果:017.25
	
	B:sql_mode未开启严格模式(sql_mode不包含strict_trans_tables)
	   插入1751.2    # 成功且警告,虽然整数位超过了指定长度,但未开严格模式,到表中的数据是999.99
	   插入-175.2    # 成功且警告,虽然加了zerofill属性(针对整数位),但未开严格模式,到表中数据是000.00
	   插入17.2      # 成功,整数位长度没超过指定长度3,小数位长度不够,用0填充,结果:017.20
	   插入17.245    # 成功,整数位长度没超过指定长度3,小数位长度超过,四舍五入,结果:017.25


-- 没加unsigned/zerofill属性
	A:sql_mode开启了严格模式(sql_mode包含strict_trans_tables)
	   插入1751.2    # 直接报错,因为开了严格模式,且指定的整数位最大长度是3
	   插入-175.2    # 成功,因为没加unsigned或zerofill属性,且整数位没超过长度
	   插入17.2      # 成功,整数位长度没超过指定长度3,小数位长度不够,用0填充,结果:17.20
	   插入17.245    # 成功,整数位长度没超过指定长度3,小数位长度超过,四舍五入,结果:17.25
	
	B:sql_mode未开启严格模式(sql_mode不包含strict_trans_tables)
	   插入1751.2    # 成功且警告,虽然整数位超过了指定长度,但未开严格模式,到表中的数据是999.99
	   插入-175.2    # 成功,因为没加unsigned或zerofill属性,且整数位没超过长度
	   插入17.2      # 成功,整数位长度没超过指定长度3,小数位长度不够,用0填充,结果:17.20
	   插入17.245    # 成功,整数位长度没超过指定长度3,小数位长度超过,四舍五入,结果:17.25

4.2 decimal数据类型的默认小数位精确度

总结

字段定义:decimal(65,30)  # 整数位最大长度35位,小数位最大长度30位
定义说明:没加unsigned和zerofill是因它们都是针对整数位,而这里讨论的是小数位,跟他们没关系
插入数据:insert into test12(d) values(1.555555555555555555555555555555);
插入说明:往test12表中的d字段插入的数据是(整数位是1,小数位是30个5)
显示结果:1.555555555555555555555555555555    <== 小数位精确度到了30位

实践

#### 创建test42表,并查看其表结构
create table if not exists test42(
  d decimal(65,30)
)engine=innodb character set utf8 collate utf8_general_ci;

mysql> desc test42;
+-------+----------------+------+-----+---------+-------+
| Field | Type           | Null | Key | Default | Extra |
+-------+----------------+------+-----+---------+-------+
| d     | decimal(65,30) | YES  |     | NULL    |       |
+-------+----------------+------+-----+---------+-------+
1 row in set (0.00 sec)


#### 插入测试数据
mysql> insert into test42(d) values(1.555555555555555555555555555555);
Query OK, 1 row affected (0.00 sec)

mysql> select * from test42;
+----------------------------------+
| d                                |
+----------------------------------+
| 1.555555555555555555555555555555 |
+----------------------------------+
1 row in set (0.00 sec)

4.3 测试unsigned属性

注意:加了unsigned属性,那么整数位就只能是正整数

sql_mode开启了严格模式,即sql_mode参数中包含strict_trans_tables

#### 当前会话模式下,sql_mode开启严格模式,DML语句自动提交
set session autocommit=on;
set session sql_mode="strict_trans_tables";


#### 创建test43_1表,并查看其表结构
create table if not exists test43_1(
  d decimal(5,2) unsigned
)engine=innodb character set utf8 collate utf8_general_ci;
   # f字段整数位的最大长度是3,小数位的最大长度是2;
   # 加了unsigned属性,那么整数位只能是正整数;
   # 若插入数据的小数位长度没有达到指定的小数位长度,则会在小数后面用零填充显示;
   # 若插入数据的小数位长度刚好达到指定的小数位长度,则不会用零填充,也不会四舍五入;
   # 若插入数据的小数位长度已经超过指定的小数位长度,则会进行四舍五入;
   
mysql> desc test43_1;
+-------+-----------------------+------+-----+---------+-------+
| Field | Type                  | Null | Key | Default | Extra |
+-------+-----------------------+------+-----+---------+-------+
| d     | decimal(5,2) unsigned | YES  |     | NULL    |       |
+-------+-----------------------+------+-----+---------+-------+
1 row in set (0.00 sec)


#### 插入测试数据
insert into test43_1(d) values(1751.2);
		# 直接报错,因为插入数值的整数位超过了指定的长度3位,且开启了严格模式
		# 数据不会到达表中

insert into test43_1(d) values(-175.2);
		# 直接报错,因为加了unsigned,整数位只能是正整数,且sql_mode开启了严格模式,
		# 数据不会到达表中

insert into test43_1(d) values(17.2);
        # 成功,插入到表中的数据是17.2,显示的时候是17.20,因为小数位长度不够2位,
        # 会在后面用零填充显示; 最终的结果是:17.20

insert into test43_1(d) values(17.245);
        # 成功,到表中的数据不是17.245,因为小数位超过指定的长度2了,会进行四舍五入
        # 最后到表中的数据是17.25,显示的时候也是17.25

mysql> select * from test43_1;
+---------+
| d       |
+---------+
|   17.20 |
|   17.25 |
+---------+
3 rows in set (0.00 sec)

sql_mode未开启严格模式,即sql_mode参数中不包含strict_trans_tables

#### 当前会话模式下,sql_mode不开启严格模式,DML语句自动提交
set session autocommit=on;
set session sql_mode="";


#### 创建test43_2表,并查看其表结构
create table if not exists test43_2(
  d decimal(5,2) unsigned
)engine=innodb character set utf8 collate utf8_general_ci;

   # f字段整数位的最大长度是3,小数位的最大长度是2;
   # 加了unsigned属性,那么整数位只能是正整数;
   # 若插入数据的小数位长度没有达到指定的小数位长度,则会在小数后面用零填充显示;
   # 若插入数据的小数位长度刚好达到指定的小数位长度,则不会用零填充,也不会四舍五入;
   # 若插入数据的小数位长度已经超过指定的小数位长度,则会进行四舍五入;
   
mysql> desc test43_2;
+-------+-----------------------+------+-----+---------+-------+
| Field | Type                  | Null | Key | Default | Extra |
+-------+-----------------------+------+-----+---------+-------+
| d     | decimal(5,2) unsigned | YES  |     | NULL    |       |
+-------+-----------------------+------+-----+---------+-------+
1 row in set (0.00 sec)


#### 插入测试数据
insert into test43_2(d) values(1751.2);
		# 成功且有警告,按理说,整数位已经超过指定的长度3了,但sql_mode未开严格模式
		# 数据会到达表中,到表中的数据是999.99

insert into test43_2(d) values(-175.2);
		# 成功且有警告,按理说,整数位应该是正整数,因为字段加了unsigned属性,但示开严格模
		# 式,数据会到达表,到表中的数据是0.00

insert into test43_2(d) values(17.2);
        # 成功,插入到表中的数据是17.2,显示的时候是17.20,因为小数位长度不够2位,
        # 会在后面用零填充显示;

insert into test43_2(d) values(17.245);
        # 成功,到表中的数据不是17.245,因为小数位超过指定的长度2了,会进行四舍五入
        # 最后到表中的数据是17.25,显示的时候也是17.25

mysql> select * from test43_2;
+--------+
| d      |
+--------+
| 999.99 |
|   0.00 |
|  17.20 |
|  17.25 |
+--------+
4 rows in set (0.00 sec)

4.4 测试zerofill属性

注意:加上zerofill会把unsigned也给带上,它针对整数位(只能插入正整数),会前导0填充

sql_mode开启了严格模式,即sql_mode参数中包含strict_trans_tables

#### 当前会话模式下,sql_mode开启严格模式,DML语句自动提交
set session autocommit=on;
set session sql_mode="strict_trans_tables";


#### 创建test44_1表,并查看其表结构
create table if not exists test44_1(
  d decimal(5,2) zerofill
)engine=innodb character set utf8 collate utf8_general_ci;

   # f字段整数位的最大长度是3,小数位的最大长度是2;
   # 加了unsigned属性,那么整数位只能是正整数;
   # 若插入数据的小数位长度没有达到指定的小数位长度,则会在小数后面用零填充显示;
   # 若插入数据的小数位长度刚好达到指定的小数位长度,则不会用零填充,也不会四舍五入;
   # 若插入数据的小数位长度已经超过指定的小数位长度,则会进行四舍五入;
   
mysql> desc test44_1;
+-------+--------------------------------+------+-----+---------+-------+
| Field | Type                           | Null | Key | Default | Extra |
+-------+--------------------------------+------+-----+---------+-------+
| d     | decimal(5,2) unsigned zerofill | YES  |     | NULL    |       |
+-------+--------------------------------+------+-----+---------+-------+
1 row in set (0.00 sec)


#### 插入测试数据
insert into test44_1(d) values(1751.2);
		# 直接报错,因为插入数值的整数位超过了指定的长度3位,且开启了严格模式
		# 数据不会到达表中

insert into test44_1(d) values(-175.2);
		# 直接报错,因为加了zerofill,整数位只能是正整数,且sql_mode开启了严格模式,
		# 数据不会到达表中

insert into test44_1(d) values(17.2);
        # 成功,插入到表中的数据是17.2,显示的时候是017.20,因为小数位长度不够2位,
        # 会在后面用零填充显示;显示的结果是017.20

insert into test44_1(d) values(17.245);
        # 成功,到表中的数据不是17.245,因为小数位超过指定的长度2了,会进行四舍五入
        # 最后到表中的数据是17.25,显示的时候是017.25

mysql> select * from test44_1;
+---------+
| d       |
+---------+
|  017.20 |
|  017.25 |
+---------+
3 rows in set (0.00 sec)

sql_mode未开启严格模式,即sql_mode参数中不包含strict_trans_tables

#### 当前会话模式下,sql_mode不开启严格模式,DML语句自动提交
set session autocommit=on;
set session sql_mode="";


#### 创建test15_1表,并查看其表结构
create table if not exists test44_2(
  d decimal(5,2) zerofill
)engine=innodb character set utf8 collate utf8_general_ci;

   # f字段整数位的最大长度是3,小数位的最大长度是2;
   # 加了unsigned属性,那么整数位只能是正整数;
   # 若插入数据的小数位长度没有达到指定的小数位长度,则会在小数后面用零填充显示;
   # 若插入数据的小数位长度刚好达到指定的小数位长度,则不会用零填充,也不会四舍五入;
   # 若插入数据的小数位长度已经超过指定的小数位长度,则会进行四舍五入;

mysql> desc test44_2;
+-------+--------------------------------+------+-----+---------+-------+
| Field | Type                           | Null | Key | Default | Extra |
+-------+--------------------------------+------+-----+---------+-------+
| d     | decimal(5,2) unsigned zerofill | YES  |     | NULL    |       |
+-------+--------------------------------+------+-----+---------+-------+
1 row in set (0.00 sec)


#### 插入测试数据
insert into test44_2(d) values(1751.2);
		# 成功且有警告,按理说,整数位已经超过指定的长度3了,但sql_mode未开严格模式
		# 数据会到达表中,到表中的数据是999.99

insert into test44_2(d) values(-175.2);
		# 成功且有警告,按理说,整数位应该是正整数,因为字段加了unsigned属性,但示开严格模
		# 式,数据会到达表,到表中的数据是000.00

insert into test44_2(d) values(17.2);
        # 成功,插入到表中的数据是17.2,显示的时候是017.20,因为小数位长度不够2位,
        # 会在后面用零填充显示;最终显示的结果是:017.20

insert into test44_2(d) values(17.245);
        # 成功,到表中的数据不是17.245,因为小数位超过指定的长度2了,会进行四舍五入
        # 最后到表中的数据是17.25,显示的时候也是017.25

mysql> select * from test44_2;
+--------+
| d      |
+--------+
| 999.99 |
| 000.00 |
| 017.20 |
| 017.25 |
+--------+
4 rows in set (0.00 sec)

4.5 测试不加unsigned/zerofill属性

注意:不加unsigned/zerofill属性,整数位就可以是正整数和负整数

sql_mode开启了严格模式,即sql_mode参数中包含strict_trans_tables

#### 当前会话模式下,sql_mode开启严格模式,DML语句自动提交
set session autocommit=on;
set session sql_mode="strict_trans_tables";


#### 创建test45_1表,并查看其表结构
create table if not exists test45_1(
  d decimal(5,2)
)engine=innodb character set utf8 collate utf8_general_ci;

   # f字段整数位的最大长度是3,小数位的最大长度是2;
   # 没有加unsigned/zerofill属性,那么整数位可以是正整数和负整数
   # 若插入数据的小数位长度没有达到指定的小数位长度,则会在小数后面用零填充显示;
   # 若插入数据的小数位长度刚好达到指定的小数位长度,则不会用零填充,也不会四舍五入;
   # 若插入数据的小数位长度已经超过指定的小数位长度,则会进行四舍五入;

mysql> desc test45_1;
+-------+--------------+------+-----+---------+-------+
| Field | Type         | Null | Key | Default | Extra |
+-------+--------------+------+-----+---------+-------+
| d     | decimal(5,2) | YES  |     | NULL    |       |
+-------+--------------+------+-----+---------+-------+
1 row in set (0.00 sec)


#### 插入测试数据进行测试
insert into test45_1(d) values(1751.2);
		# 直接报错,因为整数位超过了指定的长度3位,且开启了严格模式
		# 所以会直接报错,数据不会到达表中

insert into test45_1(d) values(-175.2);
		# 成功,因为没加unsigned/zerofill属性,整数位是可以插入正整数和负整数的
		# 整数位达到了指定长度,小数位没有达到指定长度(后面0填充)
		# 最终的结果是:-175.20

insert into test45_1(d) values(17.2);
        # 成功,因为没加unsigned/zerofill属性,整数位是可以插入正整数和负整数的
        # 整数位在指定长度范围内,小数位没有达到指定长度(后面0填充)
        # 最终的显示结果是:17.20

insert into test45_1(d) values(17.245);
        # 成功,因为没加unsigned/zerofill属性,整数位是可以插入正整数和负整数的
        # 整数位在指定长度范围内,小数位超过了指定长度会四舍五入
        # 最终的结果是:17.25

mysql> select * from test45_1;
+---------+
| d       |
+---------+
| -175.20 |
|   17.20 |
|   17.25 |
+---------+
3 rows in set (0.00 sec)

sql_mode未开启严格模式,即sql_mode参数中不包含strict_trans_tables

#### 当前会话模式下,sql_mode不开启严格模式,DML语句自动提交
set session autocommit=on;
set session sql_mode="";


#### 创建test45_2表,并查看其表结构
create table if not exists test45_2(
  d decimal(5,2)
)engine=innodb character set utf8 collate utf8_general_ci;

   # f字段整数位的最大长度是3,小数位的最大长度是2;
   # 没有加unsigned/zerofill属性,那么整数位可以是正整数和负整数
   # 若插入数据的小数位长度没有达到指定的小数位长度,则会在小数后面用零填充显示;
   # 若插入数据的小数位长度刚好达到指定的小数位长度,则不会用零填充,也不会四舍五入;
   # 若插入数据的小数位长度已经超过指定的小数位长度,则会进行四舍五入;

mysql> desc test45_2;
+-------+--------------+------+-----+---------+-------+
| Field | Type         | Null | Key | Default | Extra |
+-------+--------------+------+-----+---------+-------+
| d     | decimal(5,2) | YES  |     | NULL    |       |
+-------+--------------+------+-----+---------+-------+
1 row in set (0.00 sec)


#### 插入测试数据进行测试
insert into test45_2(d) values(1751.2);
		# 成功且有警告,因为没加unsigned/zerofill属性,整数是可以插入正整数和负整数的
		# 整数位超过了指定长度,但未开启严格模式
		# 所以最终的结果是:999.99

insert into test45_2(d) values(-175.2);
		# 成功,因为没加unsigned/zerofill属性,整数位是可以插入正整数和负整数的
		# 整数位达到了指定长度,小数位没有达到指定长度(后面0填充)
		# 最终的结果是:-175.20

insert into test45_2(d) values(17.2);
        # 成功,因为没加unsigned/zerofill属性,整数位是可以插入正整数和负整数的
        # 整数位在指定长度范围内,小数位没有达到指定长度(后面0填充)
        # 最终的显示结果是:17.20

insert into test45_2(d) values(17.245);
        # 成功,因为没加unsigned/zerofill属性,整数位是可以插入正整数和负整数的
        # 整数位在指定长度范围内,小数位超过了指定长度会四舍五入
        # 最终的结果是:17.25

mysql> select * from test45_2;
+---------+
| d       |
+---------+
|  999.99 |
| -175.20 |
|   17.20 |
|   17.25 |
+---------+
4 rows in set (0.00 sec)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值