目录
[一、 数值类](#一、 数值类)
[1.1 tinyint类型](#1.1 tinyint类型)
[3.2 decimal](#3.2 decimal)
[4.1 char类型](#4.1 char类型)
[4.2 varchar类型](#4.2 varchar类型)
[4.3 char和varchar比较](#4.3 char和varchar比较)
[4.5 enum和set类型](#4.5 enum和set类型)
数据类型分类
一、 数值类
1.1 tinyint类型
tinyint 类型大小为一字节 ,默认表示范围为**[-128,127]** ,当表示无符号整数时表示范围为**[0,255]**。
范围测试:
当插入超过范围的数据时,mysql 会阻止插入。我们再来测试插入无符号tinyint 。如果是无符号,则应该加上选项unsigned。
插入范围超过类型,mysql 会阻止。这一点和语言是不太一样的,因为C或C++中会发生截断 ,而不会阻止插入。这同时印证一件事情:如果我们已经有数据被成功插入到mysql中了 ,那么插入的数据一定是合法的!
所以,mysql中,一般而言,数据类型本身也是一种约束,关于约束后面会详细谈谈,这里先按下不表。它是为了约束使用者保证数据插入的合法性。
其他整数类型与之类似,可自行验证。
注意:尽量不使用unsigned,对于int类型可能存放不下的数据,int unsigned同样可能存放不下,与其如此,还不如设计时,将int类型提升为bigint类型。
二、bit类型
基本语法
bit[(M)]:位字段类型。M 表示每个值的位数,范围从1到64. 如果M被忽略,默认为1.
案例使用:
范围测试:
因为这里bit 类型设置只能表示一个bit位 ,所以mysql不允许插入二进制大于1的数据。
这里插入整数可以显示,为什么插入bit 位就不能呢?这是因为mysql默认是按照十进制显示的,而我们插入的是1bit位大小的数据,bit字段在显示时,是按照ASCII码对应的值显示。如果想要显示,可以控制以十六进制或者八进制的形式显示。
十六进制:
八进制:
三、小数类型
3.1float类型
语法:
float[ (m,d) ] [unsigned]:m 指定显示长度,d指定小数位数,占用空间四个字节。
说明:m表示可以显示多少位,而d表示小数位数,m-d表示可以显示的整数位数。比如说如果m为5,d为2,那么可以表示的数值范围是-999.99~999.99.
示例:
小数:float(4,2) 表示的范围是**-99.99~99.99** ,mysql 在保存值时会进行四舍五入。
当插入的数据四舍五入后属于允许范围内的数据会被保留。
而插入的数据四舍五入后大于允许范围,那么就不被允许插入:
如果加上unsigned选项呢?它会像整数那样舍弃负数部分,正数部分扩大范围吗?
示例:
这里和int类型是不一样的,浮点数类型加上unsigend选项,允许数据范围是被砍掉负数部分,只保留正数部分。
那么,默认float表示多大的范围呢?
通过示例我们可以看出**,float类型存在精度损失,float表示的精度大约为7位。如果我们为了保证精度,可以使用更加精细的类型:decimal**
3.2 decimal
语法:
decimal (m,d) [unsigned] :定点数m 指定长度,d表示小数部分位数。
* decimal(5,2)表示的范围是 -999.99 ~ 999.99
* decimal(5,2)unsigned 表示的范围是 0 ~ 999.99
decimal能表示的数据更加精确:
四、字符串类型
4.1 char类型
语法:
char(L) :固定长度字符串,L是可以存储的长度,单位为字符,最大长度值为255.
插入一些字符:
超过固定长度的大小,就不允许插入了。
在utf8 标准中,一个汉字相当于3个字节。这里char固定长度只有2个字符,为什么可以插入汉字呢?
这是因为mysql中的char大小不是字节,而是字符 。这一点和语言层面C语言,C++是不一样的。语言层面一个字符就是一个字节,而mysql中的字符,它真的代表的就是符号的个数限制。
4.2 varchar类型
语法:
varchar(L):可变长度字符串,L表示字符长度,最大长度65535个字节。
说明:
关于varchar(len) ,len到底是多大,这个len值,和表的编码密切相关:
varchar长度可以指定为0到65535之间的值,但是有1 - 3个字节用于记录数据大小,所以说有效字节数是65532.
当我们的表的编码是utf8 时,varchar(n) 的参数n最大值是65532/3=21844 [因为utf8 中,一个字符占用3个字节 ],如果编码是gbk ,varchar(n) 的参数n最大是65532/2=32766 (因为gbk 中,一个字符占用2字节)。
4.3 char和varchar比较
如何选用定长或变长字符串?
如果数据确定长度都一样,就使用定长(char),比如:身份证,手机号,md5
如果数据长度有变化,就是用变长(varchar),比如:名字,地址,密码
定长的磁盘空间比较浪费,但是效率高。
变长的磁盘空间比较节省,但是效率低。
定长的意义是直接开辟好对应的空间。变长的意义是在不超过自定义范围的情况下,用多少,开辟多少。
4.4日期和时间类型
常用的日期有如下三个:
date:日期'yyyy-mm-dd',占用三字节
datetime:时间日期格式'yyyy-mm-dd HH:ii:ss'表示范围从1000到9999,占用八字节
timestamp:时间戳,从1970年开始的yyyy-mm-dd HH:ii:ss格式和datetime完全一致,占用四字节。
时间戳是不需要外部插入数据的。
timestamp(时间戳) 不需要做操作。只要表中有时间戳,每一次只要对相关的条目,相关的列,相关的记录,对这一行的任何一个字段做更改或插入 时,时间戳会被自动更新。
既然时间戳有根据内容更改而发生变化的功能。那么datetime 的用处是什么呢?它主要让程序员去维护一个并不会随着数据更新自动更新的时间字段,它就是存储的一个固定时间。比如记录员工入职时间,记录工龄等。date只记录日期
4.5 enum和set类型
语法:
enum:枚举,"单选"类型;
enum('选项1','选项2','选项3',...);
该设定只是提供了若干个选项的值,最终一个单元格中,实际只存储了其中一个值;而且出于效率考虑,这些值实际存储的是"数字",因为这些选项的每个选项值一次对应下标。当我们添加枚举值时,也可以添加对应的下标。(后面解释)
set:集合,"多选"类型;
set('选项值1','选项值2','选项值3',...);
该设定只是提供了若干个选项的值,最终一个单元格中,设计可存储了其中任意多个值。
说明:不建议在添加枚举值,集合值的时候采用数字的方式,因为不利于阅读。
枚举类型enum ,可以直接写枚举类型限制的常量,也可以写常量对应的下标 。下标从数字1开始,分别代表第一个枚举值,第二个枚举值......
set类型不允许插入在集合中不存在的常量。可以插入一个常量,也可一次性插入多个常量。
这里相信已经注意到当插入0时,并没有显示NULL,而是什么都没显示。这是因为它表示的是空串。
那么在set中,数字是表示下标吗?
当插入3时并不是乒乓球,而是代码和羽毛球;当插入4时并不是足球,而是乒乓球。为什么呢?
这是因为,在set 类型中,这个数字不表示下标。它是类似于位图一样的结构。
set 类型中有五个常量。在mysql中,表示00000这五个bit位 ,当插入'代码'表示插入00001,当插入2,也就是00010,表示插入'羽毛球'.当插入00011,表示插入'代码'和'羽毛球'.当是4时,也就是00100,表示插入乒乓球。bit从低到高,表示从左到右在set中存储的常量。bit位为0表示不存在,为1表示存在。
所以,如果要用数字表示全部插入,应该插入11111,也就是31.
枚举enum 中数字是下标 ,而set 中数字是位图。
关于如何筛选
🖊精确筛选
语法:
select *from table_name where line_name= 常量
注:
table_name:表名
line_name:列名
常量:要筛选的内容
对于enum类型,可以根据名字筛选,也可以根据下标筛选。
对于enum类型一定是多选一。
对于set类型:
当筛选 '羽毛球' 时,它是一种准确筛选出只包含 '羽毛球' 的。而不是所有包含'羽毛球'的。这种筛选是严格匹配的。
那么如果我们想筛选到包含'羽毛球'的,该怎么操作呢?
🖊find_in_set
集合查询使用find_in_set 函数;find_in_set(sub,str_list):如果sub 在str_list 中,则返回下标;如果不在,返回0;str_list是用逗号分隔的字符串。
语法:
select find_in_set(sub,str_list);
返回了'a'在字符串中的位置。
find_in_set是查一个元素是否在对应的集合中。所以在'a,b,c'中查不到'a,b',也查不到'a,c'.
具体到表中查询:
select *from table_name where find_in_set(sub,str_list);
注:where是关键字,表示判断。
筛选出了所有包含'羽毛球'的行。
如果我们要查同时有'代码'和'羽毛球'的呢?
使用and ,它是类似于语言中的**&&**.