目录
1.MySQL中的数据类型分类
2.数值类型
tinyint类型
bit类型
小数类型
float类型
decimal类型
3.文本类型
char类型
vachar类型
varchar和char的比较
4.日期类型
5.字符串类型
enum类型
set类型
find_in_set函数
1.MySQL中的数据类型分类
数据库是用来存储数据的,存储数据首先要能够定义数据,定义数据就需要数据类型,MySQL有一套自己的数据类型。主要可以划分为:数值类型、文本类型、二进制类型、日期类型、字符串类型。
具体如下:
二进制类型:
- bolb:用于定义二进制数据。
数值类型:数值类型中又对数据类型做了更详细的划分,如下表。
数据类型 | 说明 |
bit [(m)] | 位类型:m用于指定比特位的位数,默认是1,范围是 1 ~ 64。 |
bool | 布尔类型:使用1和0表示真假。 |
tinyint [unsigned] | 有符号范围:-128 ~ 127。 无符号范围:0 ~ 255。 默认是有符号的,如果要使用无符号可以在类型后面加上 unsigned,后面的类型也是一样的。 |
smallint [unsigned] | 有符号范围:-2^15 ~ 2^15-1。 无符号范围:0 ~ 2^16-1 |
int [unsigned] | 有符号范围:-2^31 ~ 2^31-1。 无符号范围:0 ~ 2^32-1 |
bigint [unsigned] | 有符号范围:-2^63 ~ 2^63-1。 无符号范围:0 ~ 2^64-1 |
float [(m,d)] [unsigned] | m用于指定数字的个数,d用于指定小数位数,占用4字节。 |
double [(m,d)] [unsigned] | m用于指定数字的个数,d用于指定小数位数,占用8字节的空间。 表示比float精度更大的小数。 |
decimal (m,d) [unsigned] | m用于指定数字的个数,d用于指定小数位数。 用于表示精确度要求很高的数据。 |
- 该表格中 [ ] 中的内容可以省略,省略之后会使用默认值。
文本类型:文本类型中又有 char、varchar、text类型。
数据类型 | 说明 |
char(size) | 固定长度字符串,最大长度255个字符。 |
varchar(size) | 可变长度字符串,最大长度65535个字节。 |
text | 大文本类型,不支持全文索引,不支持默认值。 |
- size用于指定长度。
日期类型:
数据类型 | 说明 |
date | 只表示 年 月 日:格式为 年-月-日 |
datetime | 可以表示 年 月 日 时 分 秒:格式为 年-月-日 时:分:秒 |
timestamp | 时间戳的意思,会默认转化为date一样的格式,而且是会自动更新的。 |
字符串类型:
数据类型 | 说明 |
enum | enum是一个字符串对象,其元素的值是创建表时规定的值中的一个,使用上相当于C语言的枚举类型。 |
set | set是一个字符串对象,其元素可以有0个或者多个值,元素的值是创建表时规定值的随意组合,这些值之间用逗号隔开,因此这些值当中不能有逗号。 |
当我们往数据库表中插入数据的时候,插入的数据需要和对应的数据项的数据类型一 一匹配,如果不匹配的话,MySQL就会拦截这次插入操作,因此,数据类型本身就是数据库的一种约束。
2.数值类型
前面已经介绍过一些数值类型了,下面我想对数值类型做一下测试,以 tinyint 和 bit 为例。
tinyint类型
我们先创建一张表,然后依次插入 127 128 -128 -129,然后看结果:
- 我们发现只有 127 和 -128被插入了,说明有符号的tinyint的范围就是 -128 ~ 127。
在MySQL中,整数可以是有符号和无符号的,默认是有符号的,如果想要使用无符号的整数,需要在类型后面 加上 [unsigned]。
下面我们验证一下无符号的tinyint的取值范围,我们依次插入 255、256、0、-1:
- 我们发现只有 0 和 255被插入成功了,所以无符号的 tinyint 的取值范围确实是 0 ~ 255。
bit类型
bit [(m)] 类型:位字段类型。m用于指定比特位的位数,范围是 1 ~ 64,默认是1。
我们插入一个1,并查找:
我们看到一个很奇怪的现象,bitnum 这一列中没有我们插入的1,但是插入明明已经成功了。
这是因为,bit类型的数据在现实的时候是按照ASCII表对应的位置显示,这1对应的位置刚好是不可显的字符,所以我们就看到这个奇怪的现象了。
如果我们想要显示,可以指定使用十六进制打印:
这回我们就看到数据了。
小数类型
float类型
语法:float [(m,d)] [unsigned]
- m用于指定数字的个数。
- d用于指定小数的位数。
- unsigned用于指定数字为无符号。
- 默认占用4个字节的空间。
使用float类型需要注意,当我们插入的数字超过了指定的数字个数,MySQL会对float类型的数据进行四舍五入。
我们指定float类型的数据的m为4,d为2,然后插入 12.123、12.125:
经过MySQL的四舍五入,插入的数字都变成12.12了。
我们再来插入 123.4:
这回插入居然失败了!这是因为我们指定小数部分有两位数字,默认就有两位,没写的时候就是0,所以,我们插入的数字应该是123.40,超过了指定的4位。
我们可以插入12.3看看结果验证一下:
decimal类型
decimal类型也是小数类型的一种,只不过它能表示更加精确的小数。
语法:decimal(m,d) [unsigned]
- m用于指定数字的个数。
- d用于指定小数的位数。
- unsigned用于表明使用无符号整数。
我们定义float类型 和 decimal类型的数据进行比较:
我们发现decimal能够正确的表示精度,而float已经错乱了。说明decimal的精度确实更高。
说明:
- float表示的精度大约是7位。
- decimal(m,d)类型中m的最大取值是65,默认值是10;d的最大取值是30,默认值是0。
3.文本类型
char类型
char类型用于定义定长的字符串(在MySQL中,字符串可以用单引号引起来)。
语法:char(L)
- L是指定的长度,单位是字符。
- 最大长度是255。
我们插入指定长度为一个字符的数据:
插入成功,我们试着插入三个字符看看:
插入失败了,我们只能插入小于等于指定长度的字符串。
vachar类型
vachar用来定义变长的字符串。
语法:vachar(L)
- L是指定字符串的长度,单位是字符。
- 但是vachar的最大长度换算成字节最大是65535。
验证一下:
- 我们发现确实只能插入指定长度的字符数。
前面说,varchar换算成字节最多是65535个字节,哪最大到底是多少个字符呢?这和表的编码密切相关,在varchar类型的数据中,有1~3个字节用于记录数据大小,我们以3字节为例,所以,varchar类型标识的数据的最大字节是 65535-3=65532。
- 如果表的编码方式是utf-8,UTF-8中使用三个字节表示一个字符,所以varchar类型最大能够表示65532/3=21844个字符。
- 如果表的编码方式是gbk,gbk中使用两个字节表示一个字符,所以varchar类型最大能够表示65532/2=32766个字符。
我们可以沿着一下:创建表的时候将表的编码方式设置为utf-8。
varchar和char的比较
不是说varchar类型是用来定义变长的字符串吗?我们如何理解呢?
- 使用char(L)类型定义字符串中的 L 的意思是分配给数据的实际空间,不管你用多少,要多少就开辟多少。
- 使用varchar(L) 类型定义字符串中的 L 的意思是最大分配的空间,用多少就分配多少,但是最大不能超过L。
举个例子:假设使用三个字节表示一个字符,varchar当中使用1个字节记录数据的个数。
需要存储的数据 | 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 | 数据超过指定长度,不存储。 | 数据超过指定长度,不存储。 |
- 定长的数据比较浪费磁盘空间,但是效率高。
- 变长的数据比较节省磁盘空间,但是效率低。
- 定长的意义是:直接开辟好对应的空间。
- 变长的意义是:在不超过自定义范围的情况下,用多少,开辟多少。
那我们如何选定使用定长还是变长的字符串呢?
- 如果数据确定长度都一样,就使用定长(char),比如:身份证,手机号……
- 如果数据长度有变化,就使用变长(varchar),比如:名字,地址,但是你要保证最长的能存的进去。
4.日期类型
常用的日期类型有如下三个:
date:只能表示年月日。格式为 'y-m-d' ,占用三字节的空间。
datetime:能够表示年月日时分秒。格式为 'y-m-d 时-分-秒',占用八字节的空间。
-
最小值:
1000-01-01 00:00:00
-
最大值:
9999-12-31 23:59:59
timestamp :从1970年开始的时间戳,会自动转换成和 datetime 完全一致格式:yyyy-mm-dd HH:ii:ss,占用四字节。
- 注意,timestamp类型的数据不需要我们手动设置,会自动设置,并且转换成和datetime一样的格式。
我们创建后一张表,并向其中添加date、datetime、timestamp类型的数据:
- timestamp类型的数据可以自动添加进表中。
并且更新数据时时间戳会自动更新:
5.字符串类型
enum类型
enum类型相当于C语言中的枚举类型。
语法:enum('选项1','选项2','选项3',……);
该设定只是提供了若干个选项的值,最终一个单元格中,实际只存储了其中一个值;而且出于效率考虑,这些值实际存储的是“数字”,因为这些选项的每个选项值依次对应下标:1,2,3....最多65535个;当我们添加枚举值时,也可以添加对应的数字编号。
示例:
- 数字2就是足球的下标,就代表足球。
set类型
set类型和enum类型很像,但是set类型可以多选。
语法:set('选项值1','选项值2','选项值3', ...);
该设定只是提供了若干个选项的值,最终一个单元格中,可存储了其中任意多个值;而且出于效率考虑,这些值实际存储的是“数字”,因为这些选项的每个选项值依次对应如下数字:1,2,4,8,16,32.... 最多64个。
set中每个选项的编号不是从左往右 从1开始编址,而是按照2进制表示的数字编号的,比如:set中有三个选项,分别为 '篮球','足球','游泳',所以可以用三个比特位表示,对应关系如下:
如果我们选择篮球和足球,比特位表示就是 011,换算成10进制就是3,因此,我们选择3就相当于选择篮球和足球。
示例:
find_in_set函数
假如表中的数据如下:
我们想要查找所有爱好篮球的人,如果我们遮掩写SQL语句:
查询结果居然为空。
为了解决这个问题,MySQL提供一个在集合中查找的函数 —— find_in_set。
函数原型:find_in_set(sub,str_list)
参数:
- sub:指定搜索的值,只能是一个。
- str_list:str_list是一个用逗号分隔的字符串,表示set集合。
返回值:
- 如果 sub 在 str_list 中,则返回下标;
- 如果不在,返回0;
补充:在MySQL中select语句可以返回表达式的执行结果。例如:
因此,我们需要使用select来执行我们的函数。
我们使用这个函数查找所有爱好篮球的人:
这回就查找成功了!