前言
最近MySQL的技能树已经建成了,一直想要复习一遍MySQL的基础知识,正好趁着这次MySQL技能树的建成一起学习复习一下MySQL数据库的基本知识。也是一直在用这个数据库,有些基础的知识点长久不用就会遗忘,就比如数据类型溢出的问题,很多时候建表的时候随便给定个类似,结果导入数据的时候报错又得删表就很麻烦,如果提前做好数据长度设置可以有效的避免这个问题而且还能节省很多空间,因此对MySQL所有数据类型做个总结是一个值得的选择。
最好的总结方式就是根据学习顺序整理出一张思维导图可以帮我们很快的梳理清楚思路:
该系列文章将按照这个脉络行文,此系列文章将被纳入我的专栏一文速学SQL各类数据库操作,基本覆盖到使用SQL处理日常业务以及常规的查询建库分析以及复杂操作方方面面的问题。从基础的建库建表逐步入门到处理各类数据库复杂操作,以及专业的SQL常用函数讲解都花费了大量时间和心思创作,如果大家有需要从事数据分析或者数据开发的朋友推荐订阅专栏,将在第一时间学习到最实用常用的知识。此篇博客篇幅较长,值得细读实践一番,我会将精华部分挑出细讲实践。博主会长期维护博文,有错误或者疑惑可以在评论区指出,感谢大家的支持。
MySQL中的数值类型包括整数类型、浮点数类型和定点数类型。
一、整数类型
MySQL的整数类型以下五种:
整数类型 | 类型名称 | 存储空间 |
TINYINT | 非常小的整数 | 1个字节 |
SMALLINT | 小整数 | 2个字节 |
MEDIUMINT | 中型大小的整数 | 3个字节 |
INT(INTEGER) | 一般大小的整数 | 4个字节 |
BIGINT | 很大的整数 | 8个字节 |
在实际工作中,需要根据实际情况选择合适的整数类型。
不同的整数类型除了所需的存储空间不同外,所表示的数值范围也是不同的。不同的整数类型所表示的数值。同一种整数类型,有符号与无符号所表示的数值范围也不同。其中,有符号整数的最小值是一个负数,无符号整数的最小值是0。
如果使用的数据类型超出了整数类型的范围,则MySQL会抛出相应的错误。因此在实际使用的时候,应该首先确认好数据的取值范围,然后根据确认的结果选择合适的整数类型。
INT整数型
现在我们在mysql里面展示一下如何使用:
create table mytable1(id INT);
实际上,MySQL在执行建表语句时,int类型默认的显示宽度为11。也可以在创建数据表的时候指定数据的显示宽度。
宽度问题
创建数据表t2,将INT类型的字段id的显示宽度设置为6。
注意:整数类型的显示宽度与数据类型的取值范围无关。显示宽度只是指定最大显示的数字个数,如果在数据表中插入了大于显示宽度,但是并没有超过整数类型的数值范围的数据,依然可以正确地插入数据,并且能够正确地显示。
插入两条数据,一条数据没有超出显示的宽度6,另一条数据超出了显示的宽度6。
INSERT INTO mytable2(id) VALUES (1), (1111111);
数字1并没有超出id字段的显示宽度,数字1111111超出了id字段的显示宽度。虽然在创建数据表的时候设置了id字段的显示宽度为6,但是数字1111111并没有超出INT类型表示的数值范围,因此依然能够正确地插入数据库中并显示。
ZEROFILL自动填充
整数类型的显示宽度能够配合ZEROFILL使用。ZEROFILL表示在数字的显示位数不够时,可以用字符0进行填充。
CREATE TABLE mytable3(id1 INT ZEROFILL, id2 INT(6) ZEROFILL);
向数据表中插入数据:
INSERT INTO mytable3(id1, id2) VALUES(1, 1);
当插入的数字小于设置的显示宽度时,使用字符0进行了填充。
当整数类型设置了显示宽度并且使用字符0填充时,如果向数据表中插入时超出了显示宽度,但是并没有超出整数类型范围的数字时,MySQL也不会报错,原因是插入的数字超出了显示宽度,无须再用字符0进行填充。
所有的整数类型都有一个可选的属性UNSIGNED(无符号属性),无符号整数类型的最小取值为0。所以,如果需要在MySQL数据库中保存非负整数值时,可以将整数类型设置为无符号类型。特别地,如果在MySQL中创建数据表时,指定数据字段为ZEROFILL,则MySQL会自动为当前列添加UNSIGNED属性。
在创建数据表t3时并没有指定id1字段和id2字段的属性UNSIGNED,而只是为id1字段和id2字段指定了ZEROFILL,此时,MySQL自动为id1和id2添加了UNSIGNED属性。
在MySQL中,整数类型还有一个属性是AUTO_INCREMENT。AUTO_INCREMENT的值一般从1开始,每行自动加1。如果在标识为AUTO_INCREMENT的整数列中插入NULL,则MySQL会在此列中插入一个比该列当前最大值大1的数值。
AUTO_INCREMENT自增
一个表中最多只能有一个列被设置为AUTO_INCREMENT。设置为AUTO_INCREMENT的列需要定义为NOT NULL,并且定义为PRIMARY KEY,或者定义为NOT NULL并且定义为UNIQUE。
CREATE TABLE mytable4( id INT NOT NULL AUTO_INCREMENT PRIMARY KEY, age int );
我们直插入age数据:
INSERT INTO mytable4 (age) values(18),(20),(16);
MySQL自动为AUTO_INCREMENT类型的整型列设置了自动递增的整数值。
也可以将设置为AUTO_INCREMENT的整型列定义为UNIQUE,并没有将id字段设置为主键,而是将id字段设置为唯一索引,此时向数据表5中插入数据
MySQL同样为设置为AUTO_INCREMENT的整型列id设置了自动递增的整数值。
其他整数类型的用法与INT类型相同!
二、浮点数类型
浮点数类型主要有两种:单精度浮点数FLOAT和双精度浮点数DOUBLE。
单精度浮点数FLOAT类型占用4个字节的存储空间,双精度浮点数DOUBLE类型占用8个字节的存储空间。
对于浮点数来说,有符号与无符号所表示的数值范围也是不同的。
浮点数类型中的FLOAT和DOUBLE类型在不指定数据精度时,默认会按照实际的计算机硬件和操作系统决定的数据精度进行显示。如果用户指定的精度超出了浮点数类型的数据精度,则MySQL会自动进行四舍五入操作。
CREATE TABLE mytable6( f FLOAT, d DOUBLE );
INSERT INTO mytable6 (f, d) VALUES (3.14, 5.98);
如果我们插入一些插入超出数据类型精度的数据:
INSERT INTO mytable6 (f, d) VALUES (3.144444444444444, 5.9899999999999999);
可以看到,为FLOAT类型和DOUBLE类型插入超出数据类型精度的数据时,MySQL对插入的数据进行了四舍五入处理。
精度与标度
对于浮点数来说,可以使用(M,D)的方式进行表示,(M,D)表示当前数值包含整数位和小数位一共会显示M位数字,其中,小数点后会显示D位数字,M又被称为精度,D又被称为标度。
CREATE TABLE mytable7 ( f FLOAT(5,2), d DOUBLE(5,2) );
再次向7表中插入数据,此时在f字段中插入数值3.141,在d字段中插入数值3.14。
INSERT INTO mytable7 (f, d) VALUES (3.141, 3.14);
FLOAT类型的字段f,由于标度的长度限制,最后一位数字被舍弃了,最终插入数据库中的数值为3.14。当双精度DOUBLE类型的数据设置了精度和标度时,由于标度的限制,同样会舍弃超出标度限制的数字。
综上所述,浮点数不写精度和标度时,会按照计算机硬件和操作系统决定的数据精度进行显示。如果用户指定的精度超出了浮点数类型的数据精度,则MySQL会自动进行四舍五入操作,数据能够插入MySQL中,并能够正常显示。
三、定点数类型
MySQL中的定点数类型只有DECIMAL一种类型。DECIMAL类型也可以使用(M,D)进行表示,其中,M被称为精度,是数据的总位数;D被称为标度,表示数据的小数部分所占的位数。定点数在MySQL内部是以字符串的形式进行存储的,它的精度比浮点数更加精确,适合存储表示金额等需要高精度的数据。
DECIMAL(M,D)类型的数据的最大取值范围与DOUBLE类型一样,但是有效的数据范围是由M和D决定的。而DECIMAL的存储空间并不是固定的,由精度值M决定,总共占用的存储空间为M+2个字节。
使用定点数类型表示数据时,当数据的精度超出了定点数类型的精度范围时,则MySQL同样会进行四舍五入处理。
当DECIMAL类型不指定精度和标度时,其默认为DECIMAL(10,0)。
我们现在来建表实验一波:
CREATE TABLE mytable8 ( d1 DECIMAL, d2 DECIMAL(5, 2) );
在创建数据表8时并没有为d1字段设置精度和标度,此时,MySQL会自动为d1字段设置精度为10,标度为0。
再来插入试试看:
INSERT INTO mytable8 (d1, d2) VALUES (3.14, 3.14);
在插入数据时,d1字段的值为3,d2字段的值为3.14,再次证明了当创建数据表时,如果不给DECIMAL类型的字段设置精度和标度,则DECIMAL默认的精度为10,标度为0。此时,向数据表中插入数据会舍弃所有小数部分。
INSERT INTO mytable8 (d1, d2) VALUES (1, 3.141);
d2字段中的值,由于精度和标度的限制也被截断了。也就是说,在定点数类型中,如果小数位数超出了标度的限制,则会被截断处理。
对比浮点数类型和定点数类型,可以总结出如下不同之处:
·浮点数类型中的FLOAT类型和DOUBLE类型在不指定精度时,默认会按照计算机硬件和操作系统决定的精度进行表示;而定点数类型中的DECIMAL类型不指定精度时,默认为DECIMAL(10,0)。
·当数据类型的长度一定时,浮点数能够表示的数据范围更大,但是浮点数会引起精度问题,不适合存储高精度类型的数据。