文章目录
- 一、数据类型分类
- 二、数值类型
- 1.tinyint类型
- 2.bit类型
- 3.float类型
- 4.decimal类型
- 三、字符串类型
- 1.char类型
- 2.varchar类型
- 四、日期和时间类型
- 五、enum类型和set类型
- 1.enum类型
- 2.set类型
一、数据类型分类
MySQL的数据类型一共有如下几类,表格中简单介绍了各种数据类型以及说明:
二、数值类型
我们会发现上表中数值类型光是整型就分出了很多类,比高级语言的分类还要多。MySQL将数值类型划分得如此细粒度,原因是尽量避免空间的浪费。
1.tinyint类型
tinyint类型是小整数类型,它可以指定是有符号的还是无符号的,如果是有符号的那么取值范围是-128 ~ 127,如果是无符号的那么取值范围是0 ~ 255。默认是有符号的。
我们创建一个表,表中设置age字段,字段类型设置为tinyint无符号类型,创建好之后查看一下这个表:
2.bit类型
bit是位字段类型,在定义的时候bit后面可以带圆括号,括号里填位数,表示该字段能表示几个比特位,范围是1 ~ 64,也可以忽略,默认位数为1。
我们创建一张表使用一下bit类型:
我们向表中插入几个数据,看一下bit类型的使用,首先id插入10,a也插入10,再向id插入65,a也插入65,查看表的内容:
最后我们发现id列显示是正常的,但a列显示似乎有点不正常。其实这并不是a列显示不正常,只是MySQL在读取a列数据的时候按照ASCII码来读取,我们插入到a列的10和65都被转换成了ASCII对应的值。
3.float类型
float类型是小数类型,它也可以指定是有符号的还是无符号的,在定义float字段时要指定长度和小数位数,其定义语法为:
float [(m,d)] [unsigned]
其中m代表显示长度,即整数部分加小数部分一共有多少位,d代表小数位数。我们可以演示一下创建一张表定义一个float类型的字段,例如定义salary字段代表薪资,类型为float,显示长度设置为4,小数位数设置为2:
接下来我们向salary字段中插入一些数据来验证一下,首先插入salary为99.99,插入成功;再插入99.999,插入失败,原因是小数位数和长度都不符合;插入-99.99,插入成功;插入-99.999,插入失败:
如果我们salary插入99.995,还是插入失败,但是如果插入99.994,插入99.993,插入99.992,都能插入成功,但是一查看表中的数据内容时发现,最后真正插入进来的全都是99.99:
原因是MySQL在保存值的时候会进行四舍五入,如果四舍五入后的结果能符合一开始设定的长度,那么就可以成功插入。
4.decimal类型
decimal类型也是小数类型,它的使用方法和float基本一致,基本语法如下:
decimal (m, d) [unsigned]
其中m代表指定长度,d代表小数点位数,在使用上甚至说在绝大部分情况下decimal类型和float类型都没什么区别。但如果我们同时插入23.12345612这个数到float类型字段和decimal类型字段,就可以看出它们的区别:
我们可以发现float字段插入的时候出现了精度损失,所以这就是float和decimal的区别,decimal的精度比float更高,float表示的精度大约是7位,decimal中m的最大值是65,支持的小数位数d的最大值是30。如果decimal的d被省略,默认为0,如果m被省略,默认为10。所以如果使用高精度场景尽量使用decimal。
三、字符串类型
1.char类型
char类型是固定长度的字符串,其基本语法如下:
char (L)
其中L表示可以存储的长度,单位是字符,不是字节,char类型的最大长度值可以为255。MySQL的char类型和C/C++的char类型是不一样的,MySQL中的char类型是以字符为单位的字符串类型。
我们创建一张表演示一下char类型的使用,定义一个char类型字段,长度设置为2,代表最大长度为2个字符,我们向其插入“a”,插入成功;插入“ab”也插入成功;插入“abc”就插入失败了,原因是不满足长度要求。插入“张三”也可以插入成功;插入“王老五”就插入失败了,原因是不满足长度要求:
2.varchar类型
varchar类型也是字符串类型,它是可变长字符串,基本语法如下:
varchar(L)
其中L表示字符串的最大长度,单位也是字符,最大长度可以达到65535个字节。我们可以演示一下varchar的使用,与上面的char类型测试保持一致,最大长度设置为2。首先插入“a”,可以插入成功;然后插入“ab”也可以插入成功;插入“abc”就插入失败了,原因是不满足长度要求。插入“张三”也可以插入成功;插入“王老五”就插入失败了,原因也是不满足长度要求:
从这里看来,varchar和char没有任何区别,为什么要多一个varchar类型呢?为什么varchar类型又叫做可变长字符串呢?
其实,varchar的可变长并不是指它的上限可变长,如果字符串的长度超过了varchar规定的长度上限,同样是不能插入的。这里的可变长指的是空间的可变长。
varchar的长度可以指定为0 ~ 65536之间的值,但是有1 ~ 3个字节是用来记录数据大小的,所以说有效的字符串所占字节数最大是65532。那么char类型和varchar类型有什么区别呢?下面的表格就可以很好地诠释两者之间的区别:
实际存储 | char(4) | varchar(4) | char占用字节 | varchar占用字节 |
---|---|---|---|---|
abcd | abcd | abcd | 4*3=12 | 4*3+1=13 |
A | A | A | 4*3=12 | 1*3+1=4 |
abcde | × | × | 数据超过长度 | 数据超过长度 |
从上面的表格我们可以看出,同样是设置了最大长度是4的char类型和varchar类型,当插入的值是“abcd”四个字符时,char类型占用的字节是12个,varchar类型占用的字节是13个,原因是varchar需要多一个字节来记录数据的大小。但是如果插入的值是“A”,char类型占用的字节依旧是12个,原因是char类型是定长的,这里的定长指的是空间定长,在被定义的时候char类型就开辟好了那么大的空间,就算没有使用完也是要占那么大的空间。但varchar类型就不一样了,此时varchar类型占用的字节是4个,原因是varchar类型是可变长的,这里也指的是空间,varchar类型不会在一开始固定空间大小,而是需要多少空间就给多少空间,所以这就是char类型和varchar类型的区别。
如何选择char类型和varchar类型:
- 如果可以确定数据的长度都是一样的,那就使用char类型,比如身份证、手机号等。
- 如果数据长度是有变化的,那就使用varchar类型,比如名字、地址等。但是需要保证最长的数据也能存储进去。
- char类型比较浪费磁盘空间,但是效率比较高。
- varchar类型比较节省磁盘空间,但是效率比较低。
总之,char类型的意义是直接开辟好对应的空间,varchar类型的意义是在不超过自定义长度的情况下,需要使用多少空间就开辟多少空间。
四、日期和时间类型
MySQL有三个日期和时间类型:
- date:日期类型,只能用来表示日期,格式为
year-month-day
,占用3个字节。 - datetime:日期时间类型,可以用来表示日期和时间,格式为
year-month-day hour:minute:second
,表示范围从1000 ~ 9999,占用8个字节。 - timestamp:时间戳类型,表示从
1970-01-01 00:00:00
开始到现在的秒数,该类型的显示格式和datetime完全一致,占用4个字节。
下面我们创建一张表演示一下三种日期和时间类型的使用:
五、enum类型和set类型
1.enum类型
enum类型是枚举类型,它是用来提供可选择的选项的,并且是单选类型,基本语法如下:
enum ('选项1', '选项2', ...)
在设定enum类型字段的时候需要将所有可以被选择的选项枚举出来,最终插入数据的时候,enum类型只能选择一个选项,因为enum类型是单选类型。出于效率的考虑,这些选项值实际存储的是数字,这些选项值在底层其实依次对应1 ~ 65535的数字。所以在我们添加枚举值时,也可以添加对应的数字编号。
我们可以建一个表演示一下enum类型的使用,添加一个名为sex的字段,字段类型为enum,可供选择的选项只有“男”和“女”,然后我们向表中插入数据:
如果我们想查询表格中性别为男的所有人,输入语句select * from t8 where sex='男';
,即可查询出结果:
2.set类型
set类型是集合类型,它也是用来提供选项的,只不过它是用来提供多选的,基本语法如下:
set ('选项值1', '选项值2', ...)
set类型在定义的时候需要将所有可供选择的选项都枚举出来,在插入数据的时候可以选择任意多个选项。而且出于效率考虑,这些选项值其实在底层也是数字,它在底层是位图结构,最多有64位。比如第一个选项就代表第一个比特位,以此类推。
我们也可以建一个表演示一下set类型的使用,添加一个名为hobby的字段,字段类型为set,可供选择的选项分别有:“游泳”、“唱歌”、“跳舞”、“rap”、“篮球”、“足球”,然后我们向表中插入数据:
如果我们想查询爱好是篮球的所有人,输入语句select * from t9 where hobby='篮球';
,查出来的结果发现并不符合要求,它只给我们查出来了只喜欢打篮球的人,有一些既喜欢打篮球又喜欢唱跳rap的人并没有被查出来:
所以set的查询需要使用到复合查询函数find_in_set,函数基本使用如下:
如果sub在str_list中,则返回对应的下标,如果不在,则返回0。str_list是用逗号分隔开的字符串。
find_in_set(sub, str_list);
例如我们现在想在刚才的表格中查找喜欢篮球的所有人,输入语句select * from t9 where find_in_set('篮球', hobby);