文章目录

  • 一、数据类型分类
  • 二、数值类型
    • 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占用字节
abcdabcdabcd4*3=124*3+1=13
AAA4*3=121*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);