一、整数类型
根据表示一个数占用字节数的不同,MySQL把整数划分成如下所示的类型:
类型 | 占用的存储空间(单位:字节) | 无符号数取值范围 | 有符号数取值范围 | 含义 |
---|---|---|---|---|
TINYINT | 1 | 0 ~ 2⁸-1 | -2⁷ ~ 2⁷-1 | 非常小的整数 |
SMALLINT | 2 | 0 ~ 2¹⁶-1 | -2¹⁵ ~ 2¹⁵-1 | 小的整数 |
MEDIUMINT | 3 | 0 ~ 2²⁴-1 | -2²³ ~ 2²³-1 | 中等大小的整数 |
INT(别名:INTEGER) | 4 | 0 ~ 2³²-1 | -2³¹ ~ 2³¹-1 | 标准的整数 |
BIGINT | 8 | 0 ~ 2⁶⁴-1 | -2⁶³ ~ 2⁶³-1 | 大整数 |
以TINYINT为例,用1个字节,也就是8个位表示有符号数的话,就是既可以表示正数,也可以表示负数的话,需要有一个比特位表示正负号。但是如果表示无符号数的话,也就是只表示非负数的话,就不需要表示正负号,这是有符号数和无符号数的区别。
光说不练假把式,我们来逐个验证自己的想法。
创建一张测试表:
CREATE TABLE test_int1(
f1 TINYINT,
f2 SMALLINT,
f3 MEDIUMINT,
f4 INTEGER,
f5 BIGINT
);
来看下具体的表结构:
mysql> desc test_int1;
+-------+--------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+-------+--------------+------+-----+---------+-------+
| f1 | tinyint(4) | YES | | NULL | |
| f2 | smallint(6) | YES | | NULL | |
| f3 | mediumint(9) | YES | | NULL | |
| f4 | int(11) | YES | | NULL | |
| f5 | bigint(20) | YES | | NULL | |
+-------+--------------+------+-----+---------+-------+
5 rows in set (0.00 sec)
我们对f1赋值为-1:
mysql> insert into test_int1(f1) value (-1);
Query OK, 1 row affected (0.00 sec)
mysql> select * from test_int1;
+------+------+------+------+------+
| f1 | f2 | f3 | f4 | f5 |
+------+------+------+------+------+
| -1 | NULL | NULL | NULL | NULL |
+------+------+------+------+------+
1 row in set (0.00 sec)
由于tinyint范围是 -128~127 ,当赋值超过127时,就会报错:
mysql> insert into test_int1(f1) value (128);
ERROR 1264 (22003): Out of range value for column 'f1' at row 1
可以看出来,创建后默认当作是有符号数,就是说有一个比特位表示正负号,比如tinyint就只有7个比特来表示数字,因此它的范围是:-128~127 。
除非我们指定f1是无符号数(非负),此时f1就变成了非负数,也不需要有一个单独的比特位来表示正负了,用8个比特来表示数字,范围为0-255 。
如何指定其为无符号数呢?在类型后面增加unsigned
即可,比如int unsigned
就可以指定为无符号的int类型了。
我们以f1字段为例进行修改和测试:
mysql> alter table test_int1 modify f1 tinyint unsigned;
Query OK, 0 rows affected (0.03 sec)
Records: 0 Duplicates: 0 Warnings: 0
mysql> select * from test_int1;
Empty set (0.00 sec)
mysql> insert into test_int1(f1) value (-1);
ERROR 1264 (22003): Out of range value for column 'f1' at row 1
mysql>
mysql>
mysql> insert into test_int1(f1) value (255);
Query OK, 1 row affected (0.00 sec)
mysql> select * from test_int1;
+------+------+------+------+------+
| f1 | f2 | f3 | f4 | f5 |
+------+------+------+------+------+
| 255 | NULL | NULL | NULL | NULL |
+------+------+------+------+------+
1 row in set (0.00 sec)
mysql> insert into test_int1(f1) value (256);
ERROR 1264 (22003): Out of range value for column 'f1' at row 1
下面继续看个问题,我们再来看下一开始创建的表结构:
mysql> desc test_int1;
+-------+--------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+-------+--------------+------+-----+---------+-------+
| f1 | tinyint(4) | YES | | NULL | |
| f2 | smallint(6) | YES | | NULL | |
| f3 | mediumint(9) | YES | | NULL | |
| f4 | int(11) | YES | | NULL | |
| f5 | bigint(20) | YES | | NULL | |
+-------+--------------+------+-----+---------+-------+
5 rows in set (0.00 sec)
答案:不会对插入的数据有任何影响,还是按照类型的实际宽度进行保存,即显示宽度与类型可以存储的值范围无关。从MySQL 8.0.17开始,整数数据类型不推荐使用显示宽度属性。
mysql> CREATE TABLE test_int2( f1 INT, f2 INT(5), f3 INT(5) ZEROFILL );
Query OK, 0 rows affected (0.03 sec)
mysql> desc test_int2;
+-------+--------------------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+-------+--------------------------+------+-----+---------+-------+
| f1 | int(11) | YES | | NULL | |
| f2 | int(5) | YES | | NULL | |
| f3 | int(5) unsigned zerofill | YES | | NULL | |
+-------+--------------------------+------+-----+---------+-------+
3 rows in set (0.00 sec)
根据上面所述,int的有符号数取值范围是-2³¹ ~ 2³¹-1,换算下来其实是-2147483648~2147483647,其范围足足有大约42亿,是不是很大?
此时分别为f1、f2、f3赋值为12,看下效果:
mysql> insert into test_int2(f1,f2,f3) values(12,12,12);
Query OK, 1 row affected (0.00 sec)
mysql> select * from test_int2;
+------+------+-------+
| f1 | f2 | f3 |
+------+------+-------+
| 12 | 12 | 00012 |
+------+------+-------+
1 row in set (0.00 sec)
f1和f2无异议,f3变成了00012,这里就不得不解释下“ZEROFILL”的含义了,其规则为:
ZEROFILL: 0填充,(如果某列是ZEROFILL,那么MySQL会自动为当前列添加UNSIGNED属性),如果指定了ZEROFILL只是表示不够M位时,用0在左边填充,如果超过M位,只要不超过数据存储范围即可。
下面我们来对f1、f2、f3都赋值为12345试试:
mysql> update test_int2 set f1=12345,f2=12345,f3=12345;
Query OK, 1 row affected (0.00 sec)
Rows matched: 1 Changed: 1 Warnings: 0
mysql> select * from test_int2;
+-------+-------+-------+
| f1 | f2 | f3 |
+-------+-------+-------+
| 12345 | 12345 | 12345 |
+-------+-------+-------+
1 row in set (0.01 sec)
可以看到f3已经被5位填满,也就正常展示没有0的填充了。
下面我们继续增大,对f1、f2、f3赋值为123456,看看会不会报错:
mysql> update test_int2 set f1=123456,f2=123456,f3=123456;
Query OK, 1 row affected (0.00 sec)
Rows matched: 1 Changed: 1 Warnings: 0
mysql> select * from test_int2;
+--------+--------+--------+
| f1 | f2 | f3 |
+--------+--------+--------+
| 123456 | 123456 | 123456 |
+--------+--------+--------+
1 row in set (0.00 sec)
-
首要原则:首先确保数据不会超过取值范围,在这个前提之下,再去考虑如何节省存储空间。 -
我们在选择列的数据类型时,在满足业务需求的前提下,应遵循“最小”原则,选择“最小”的数据类型,能占用更少的存储空间并获得更高的查询效率; -
比如存储性别,由于只有男、女、未知这三种类型,那么工程实现上只需要存储0、1、2三种即可满足业务条件,tinyint是比较好的选择;
二、浮点数类型
9.875 = 8 + 1 + 0.5 + 0.25 + 0.125 = 1 × 2³ + 1 × 2⁰ + 1 × 2⁻¹ + 1 × 2⁻² + 1 × 2⁻³
-
符号部分,占用1个比特位即可。 -
指数部分,视具体浮点数格式而定。 -
尾数部分,视具体浮点数格式而定。
-
sign: 符号位, 即图中蓝色的方块 -
biased exponent: 指数位, 即图中绿色的方块 -
fraction: 尾数位, 即图中红色的方块
类型 | 占用的存储空间(单位:字节) | 绝对值最小非0值 | 绝对值最大非0值 | 含义 |
---|---|---|---|---|
FLOAT | 4 | (-3.402823466E+38,-1.175494351E-38),0,(1.175494351E-38,3.402823466E+38) | 0,(1.175494351E-38,3.402823466E+38) | 单精度浮点数 |
DOUBLE | 8 | (-1.7976931348623157E+308,-2.2250738585072014E-308),0,(2.2250738585072014E-308,1.7976931348623157E+308) | 0,(2.2250738585072014E-308,1.7976931348623157E+308) | 双精度浮点数 |
这里注意,范围由二进制转换为了我们熟知的十进制的值来表示了,这里采取科学计数法来表示,科学记数法的形式是由两个数的乘积组成的,表示为a×10^b(aEb)。
-
https://zhuanlan.zhihu.com/p/343033661 -
https://zhuanlan.zhihu.com/p/343037540 -
https://zhuanlan.zhihu.com/p/343040291
举个例子看一下,设置了M和D的单精度浮点数的取值范围的变化:
类型 | 取值范围 |
---|---|
FLOAT(4, 1) | -999.9~999.9 |
FLOAT(5, 1) | -9999.9~9999.9 |
FLOAT(6, 1) | -99999.9~99999.9 |
FLOAT(4, 0) | -9999~9999 |
FLOAT(4, 1) | -999.9~999.9 |
FLOAT(4, 2) | -99.99~99.99 |
-
FLOAT和DOUBLE类型在不指定(M,D)时,默认会按照实际的精度(由实际的硬件和操作系统决定)来显示。 -
对于浮点数来说,如果存储时,整数部分超出了范围,MySQL就会报错,不允许存这样的值;如果存储时,小数点部分若超出范围,就分以下情况: -
若四舍五入后,整数部分没有超出范围,则只警告,但能成功操作并四舍五入删除多余的小数位后保存。例如在FLOAT(5,2)列内插入999.009,近似结果是999.01。 -
若四舍五入后,整数部分超出范围,则MySQL报错,并拒绝处理。如FLOAT(5,2)列内插入999.995和-999.995都会报错。
CREATE TABLE test_float_double(
f1 FLOAT,
f2 FLOAT(5,2),
f3 FLOAT(10,6),
f4 DOUBLE
);
得到如下表结构:
mysql> desc test_float_double;
+-------+--------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+-------+--------------+------+-----+---------+-------+
| f1 | float | YES | | NULL | |
| f2 | float(5,2) | YES | | NULL | |
| f3 | float(10,6) | YES | | NULL | |
| f4 | double | YES | | NULL | |
+-------+--------------+------+-----+---------+-------+
4 rows in set (0.00 sec)
首先对f1赋值一个小数,比如123.45:
mysql> insert into test_float_double(f1) value(123.45);
Query OK, 1 row affected (0.00 sec)
mysql> select * from test_float_double;
+--------+------+------+------+
| f1 | f2 | f3 | f4 |
+--------+------+------+------+
| 123.45 | NULL | NULL | NULL |
+--------+------+------+------+
1 row in set (0.00 sec)
-
float单精度小数部分只能精确到后面6位,加上小数点前的一位,即有效数字为7位 -
double双精度小数部分能精确到小数点后的15位,加上小数点前的一位有效位数为16位
mysql> update test_float_double set f1=9.99999;
Query OK, 1 row affected (0.00 sec)
Rows matched: 1 Changed: 1 Warnings: 0
mysql> select * from test_float_double;
+---------+------+------------+
| f1 | f2 | f3 |f4 |
+---------+------+------------+
| 9.99999 | NULL | NULL | NULL|
+---------+------+------------+
1 row in set (0.00 sec)
再次增加一个小数时,触发了四舍五入:
mysql> update test_float_double set f1=9.999999;
Query OK, 1 row affected (0.00 sec)
Rows matched: 1 Changed: 1 Warnings: 0
mysql> select * from test_float_double;
+------+------+------------+------+
| f1 | f2 | f3 | f4 |
+------+------+------------+------+
| 10 | NULL | NULL | NULL | NULL|
+------+------+------------+------+
1 row in set (0.00 sec)
这么算来,实际上精度也就达到了6位有效数字,不过对于我们一般的业务来说,能达到这个程度已经足够。
再来看下f2,我们指定了FLOAT(5,2),即整数位:3,小数位:2,如果赋值为123.456,那么就会超出小数范围,触发四舍五入:
mysql> update test_float_double set f2=123.45;
Query OK, 1 row affected (0.00 sec)
Rows matched: 1 Changed: 1 Warnings: 0
mysql> select * from test_float_double;
+----------+--------+------------+------+
| f1 | f2 | f3 | f4 |
+----------+--------+------------+------+
| NULL | 123.45 | NULL | NULL |
+----------+--------+------------+------+
1 row in set (0.00 sec)
mysql> update test_float_double set f2=123.456;
Query OK, 1 row affected (0.00 sec)
Rows matched: 1 Changed: 1 Warnings: 0
mysql> select * from test_float_double;
+----------+--------+------------+------+
| f1 | f2 | f3 | f4 |
+----------+--------+------------+------+
| NULL | 123.46 | NULL | NULL |
+----------+--------+------------+------+
1 row in set (0.00 sec)
由于f2的整数部分只有三位,一旦四舍五入导致其超出999,那么就会报错,我们来尝试赋值为999.999,此时触发四舍五入看是否会报错:
mysql> update test_float_double set f2=999.999;
ERROR 1264 (22003): Out of range value for column 'f2' at row 1
f3字段设置为了FLOAT(10,6),即整数位:4,小数位:6,我们对其赋值为32.214412
:
mysql> update test_float_double set f3=32.214412;
Query OK, 1 row affected (0.00 sec)
Rows matched: 1 Changed: 1 Warnings: 0
mysql> select * from test_float_double;
+----------+--------+-----------+------+
| f1 | f2 | f3 | f4 |
+----------+--------+-----------+------+
| NULL | 999.99 | 32.214413 | NULL |
+----------+--------+-----------+------+
1 row in set (0.00 sec)
32.214412
,但结果显示32.214413
,最后一位相差一个数字,这就是float不准确的一个具体表现了。float会尽可能地寻找近似的值存储,以保证精度。这一切都是因为我们的计算机是以二进制存储的,面对这种除不尽的场景时,加之float只有32位的空间,必定要发生截取,以一个近似值去存储,此时就会出现误差。说到底,小数相对于整数来说,压根不能穷举,比如范围是0-10,整数个数是11个是可穷举出来的,但是0-10之间的小数有多少个呢?答案自然是无穷。即便加上限制条件,最大到6位小数,此时是可以穷举了,但是不能涵盖除不尽这种情况,毕竟计算机是以二进制存储的,比如上文中提到的0.3如何用二进制表示出来,所以计算机只能尽可能地寻找到它自己能表示出来的并且最接近这个小数的值了,也就会出现一些结果上的偏差。
mysql> update test_float_double set f3=32.015625;
Query OK, 1 row affected (0.01 sec)
Rows matched: 1 Changed: 1 Warnings: 0
mysql> select * from test_float_double;
+----------+--------+-----------+------+
| f1 | f2 | f3 | f4 |
+----------+--------+-----------+------+
| NULL | 999.99 | 32.015625 | NULL |
+----------+--------+-----------+------+
1 row in set (0.01 sec)
下面来看看double,精度上会相对于float增加不少,毕竟空间存储上是float的两倍。我们先拿32.214412
小试牛刀,float不行,double应该是可以的,我们来确定下,这次给f4字段赋值。
mysql> update test_float_double set f4=32.214412;
Query OK, 1 row affected (0.00 sec)
Rows matched: 1 Changed: 1 Warnings: 0
mysql> select * from test_float_double;
+----------+--------+-----------+-----------+
| f1 | f2 | f3 | f4 |
+----------+--------+-----------+-----------+
| NULL | 999.99 | 32.015625 | 32.214412 |
+----------+--------+-----------+-----------+
1 row in set (0.00 sec)
可以看到,f4正确无误地保存了该值,说明遇到这种小数较多的业务时,可能得考虑是否需要使用double才行了。
mysql> update test_float_double set f4=32.214415123456789;
Query OK, 1 row affected (0.00 sec)
Rows matched: 1 Changed: 1 Warnings: 0
mysql> select * from test_float_double;
+----------+--------+-----------+-------------------+
| f1 | f2 | f3 | f4 |
+----------+--------+-----------+-------------------+
| NULL | 999.99 | 32.015625 | 32.21441512345679 |
+----------+--------+-----------+-------------------+
1 row in set (0.00 sec)
mysql> update test_float_double set f4=2.2144151234567891;
Query OK, 1 row affected (0.01 sec)
Rows matched: 1 Changed: 1 Warnings: 0
mysql> select * from test_float_double;
+----------+--------+-----------+-------------------+
| f1 | f2 | f3 | f4 |
+----------+--------+-----------+-------------------+
| 0.214414 | 999.99 | 32.015625 | 2.214415123456789 |
+----------+--------+-----------+-------------------+
1 row in set (0.01 sec)
-
double为了提高精度,牺牲了不少存储空间,这必然会提高存储和计算的压力,如果不是业务必须,float已经足够使用了; -
从MySQL 8.0.17开始,FLOAT(M,D) 和DOUBLE(M,D)用法在官方文档中已经明确不推荐使用,将来可能被移除。另外,关于浮点型FLOAT和DOUBLE的UNSIGNED也不推荐使用了,将来也可能被移除。 -
在编程中,如果用到浮点数,要特别注意误差问题,因为浮点数是不准确的,所以我们要避免使用“=”来判断两个数是否相等。同时,在一些对精确度要求较高的项目中,千万不要使用浮点数,不然会导致结果错误,甚至是造成不可挽回的损失。那么,MySQL 有没有精准的数据类型呢?当然有,这就是定点数类型:DECIMAL。
三、定点数类型
正因为用浮点数表示小数可能会有不精确的情况,在一些情况下我们必须保证小数是精确的,所以MySQL提供一种称之为定点数的数据类型,它也是存储小数的一种方式:
类型 | 占用的存储空间(单位:字节) | 取值范围 |
---|---|---|
DECIMAL(M, D) | 取决于M和D | 取决于M和D |
-
当DECIMAL类型不指定精度和标度时,其默认为DECIMAL(10,0),表示有10个整数位,0个小数位,其范围:-9999999999~9999999999。当数据的精度超出了定点数类型的精度范围时,则MySQL同样会进行四舍五入处理。 -
DECIMAL 的存储空间并不是固定的,和M、D的取值有关。
mysql> CREATE TABLE test_decimal_1(
f1 DECIMAL,
f2 DECIMAL(5,2) ,
f3 DECIMAL(10,6));
Query OK, 0 rows affected (0.03 sec)
mysql> desc test_decimal_1;
+-------+---------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+-------+---------------+------+-----+---------+-------+
| f1 | decimal(10,0) | YES | | NULL | |
| f2 | decimal(5,2) | YES | | NULL | |
| f3 | decimal(10,6) | YES | | NULL | |
+-------+---------------+------+-----+---------+-------+
3 rows in set (0.00 sec)
首先,表结构佐证了第一点:当DECIMAL类型不指定精度和标度时,其默认为DECIMAL(10,0),表示有10个整数位,0个小数位,其范围:-9999999999~9999999999。
f2的类型是decimal(5,2),表示其整数位有三位,小数位有两位。f3的类型是decimal(10,6),表示其整数位有四位,小数位有六位。
首先我们对f1和f2分别赋值123.12:
mysql> insert into test_decimal_1 (f1,f2) values(123.12,123.12);
Query OK, 1 row affected, 1 warning (0.01 sec)
mysql> select * from test_decimal_1;
+------+--------+------+
| f1 | f2 | f3 |
+------+--------+------+
| 123 | 123.12 | NULL |
+------+--------+------+
1 row in set (0.00 sec)
由于f1的小数位是0,因此被四舍五入为123保存,而f2是正好满足两位小数的,因此可以完整保存下来。
下面我们增加小数位,对f1和f2分别赋值123.123:
mysql> update test_decimal_1 set f1=123.123,f2=123.123;
Query OK, 0 rows affected, 2 warnings (0.00 sec)
Rows matched: 1 Changed: 0 Warnings: 2
mysql> select * from test_decimal_1;
+------+--------+------+
| f1 | f2 | f3 |
+------+--------+------+
| 123 | 123.12 | NULL |
+------+--------+------+
1 row in set (0.00 sec)
此时f1仍然四舍五入保持不变,但是f2由于小数位只能精确到2位,因此后面的3也被四舍五入了。
当超出范围时会报错,相信这很好理解:
mysql> update test_decimal_1 set f1=1234.123,f2=1234.123;
ERROR 1264 (22003): Out of range value for column 'f2' at row 1
总结:与浮点数有一个相同的特性,那就是整数位超出范围会直接报错,小数位超出范围会四舍五入。
我们最后再来看下f3,f3的类型是decimal(10,6),表示其整数位有四位,小数位有六位。当我们赋值f3为32.214412,看看会不会跟float(10,6)一样出现误差问题:
mysql> update test_decimal_1 set f3=32.214412;
Query OK, 1 row affected (0.00 sec)
Rows matched: 1 Changed: 1 Warnings: 0
mysql> select * from test_decimal_1;
+------+--------+-----------+
| f1 | f2 | f3 |
+------+--------+-----------+
| 124 | 123.13 | 32.214412 |
+------+--------+-----------+
1 row in set (0.00 sec)
可以看到f3分毫不差地保存了下来,这就是与浮点数最大的不同了。
四、浮点数的计算误差问题
当我们对数据库中的小数进行一些计算时,我们会发现很多奇怪的现象。
我们创建一张表,插入三条double类型的数据,对其进行求和运算:
mysql> CREATE TABLE test_double2( f1 DOUBLE );
Query OK, 0 rows affected (0.03 sec)
mysql> desc test_double2;
+-------+--------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+-------+--------+------+-----+---------+-------+
| f1 | double | YES | | NULL | |
+-------+--------+------+-----+---------+-------+
1 row in set (0.00 sec)
mysql> INSERT INTO test_double2 VALUES(0.47),(0.44),(0.19);
Query OK, 3 rows affected (0.00 sec)
Records: 3 Duplicates: 0 Warnings: 0
mysql> select * from test_double2;
+------+
| f1 |
+------+
| 0.47 |
| 0.44 |
| 0.19 |
+------+
3 rows in set (0.00 sec)
mysql> select sum(f1) from test_double2;
+--------------------+
| sum(f1) |
+--------------------+
| 1.0999999999999999 |
+--------------------+
1 row in set (0.00 sec)
按理说:0.47+0.44+0.19 = 1.1,而不是奇怪的1.0999999999999999。此时我们将类型改为decimal就可以解决此问题了。
mysql> CREATE TABLE test_decimal_2( f1 decimal(5,2) );
Query OK, 0 rows affected (0.03 sec)
mysql> desc test_decimal_2;
+-------+--------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+-------+--------------+------+-----+---------+-------+
| f1 | decimal(5,2) | YES | | NULL | |
+-------+--------------+------+-----+---------+-------+
1 row in set (0.01 sec)
mysql> INSERT INTO test_decimal_2 VALUES(0.47),(0.44),(0.19);
Query OK, 3 rows affected (0.00 sec)
Records: 3 Duplicates: 0 Warnings: 0
mysql> select * from test_decimal_2;
+------+
| f1 |
+------+
| 0.47 |
| 0.44 |
| 0.19 |
+------+
3 rows in set (0.00 sec)
mysql> select sum(f1) from test_decimal_2;
+---------+
| sum(f1) |
+---------+
| 1.10 |
+---------+
1 row in set (0.00 sec)
这里输出了我们预期的1.10,因此为了保证精确度,尤其是金融行业,请务必不要使用浮点数造成不必要的被迫离职烦恼。
五、DECIMAL存储空间如何计算
Values for DECIMAL columns are stored using a binary format that packs nine decimal digits into 4 bytes. The storage requirements for the integer and fractional parts of each value are determined separately. Each multiple of nine digits requires 4 bytes, and any remaining digits left over require some fraction of 4 bytes.
组中包含的十进制位数 | 占用存储空间大小(单位:字节) |
---|---|
1或2 | 1 |
3或4 | 2 |
5或6 | 3 |
7或8或9 | 4 |
-
1、字段decimal(18,9),18-9=9,这样整数部分和小数部分都是9,那两边分别占用4个字节,一共占用8个字节; -
2、字段decimal(20,6),20-6=14,其中小数部分为6,就对应上表中的3个字节,而整数部分为14,14-9=5,就是4个字节再加上表中的3个字节,所以一共加起来是3+4+3=10个字节。
六、总结
-
MySQL中数值类型主要分为哪几种? -
整数类型有哪些?这些类型比如常用的INT的范围是多少? -
有符号数和无符号数是什么含义、对于数值类型来说范围发生了什么变化?使用什么关键字? -
ZEROFILL属性是什么、ZEROFILL属性你在实际工程中有用过吗?扩展想下这个属性有啥意义? -
经典问题:INT(M)的M是什么含义?当插入的数据长度超过M时会发生什么? -
浮点数类型有哪些?浮点数如何表示?浮点数为什么不精确?float和double的区别? -
定点数类型有哪些?为什么要用decimal?decimal的表示方式?deciaml类型底层如何存储?存储空间如何计算的? -
各种类型的适用场景、实际业务中选择类型时应当遵循什么原则?
原文始发于微信公众号(幕后哈土奇):06|第六话:基础篇-MySQL数据类型之数值类型
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/112897.html