【MySQL】数据类型

目录

数据类型分类

数值类型

整数类型

字节类型

浮点数类型

字符串类型

日期和时间类型

enum和set


数据类型分类


之前我们建库、表,都是对库、表这种结构操作,并没有对内容进行操作,都是DDL。现在,我们就要对里面的数据进行操作了。
注意:上面的这些类型是不区分大小写的

数值类型

整数类型

整数类型包含tinyint、smallint、int、bigint这四种,我们以tinyint为例,其余都是类似的。
tinyint只有1个字节大小,是带符号的。tinyint unsigned是不带符号的。

我们创建一个表,这个表中只有一个tinyint类型的数据

我们试着向这个表中插入一些数据

可以看到,我们插入在tinyint类型范围内的数据是没问题的,再来看看插入范围之外的数据会如何

可以看到,当我们插入的数据超过了类型的范围时,MySQL会直接拦截,不让你进行操作

在C/C++中,我们写char a = 12345;很明显,12345已经超过了char的数据范围,C/C++会发生截断,而不是直接拦截。而MySQL会直接拦截,这也就保证了MySQL中插入的数据一定是合法的、可预期的(数据范围是确定的)、完整的(不会发生截断等操作)。所以,MySQL中数据本身就是一种约束。

一般不推荐使用无符号的类型,因为数据使用有符号的无法表示,那么使用无符号的也大概率无法表示。不过,实际选择要根据实际场景和空间。

字节类型

基本语法

bit[(M)] : 位字段类型。M表示每个值的位数,范围从1到64。如果M被忽略,默认为1。

创建一个有bit类型的表,并向其中插入一些数据

此时会发现,我们给位类型插入了0和1,但却什么都没有显示,这是为什么呢?
因为查看位类型时,是根据ASCII来显示的,而ASCII中0和1的值是看不见的,若我们向看到,可以将其转到十进制来看

证明:bit类型是根据ASCII来显示的

可以看到,我们插入97,然后显示出来的是a,所以,查看bit类型时是根据ASCII来显示的

创建表时,若字节类型的位数大于64也是会被拦截的

desc查出来bit后括号内的数字表示的就是这个变量带几个比特位

这说明t2这张表中,online这个变量带10个比特位。

浮点数类型

浮点数类型有float、double、decimal

float

float[(m, d)] [unsigned] : m指定显示长度,d指定小数位数,占用空间4个字节

创建一个有浮点数类型的表
这个表中浮点数后面的数字是(4, 2),表示的是浮点数的长度是4,其中小数点后有2位数,且默认是有符号的,所以范围是[-99.99, 99.99]


可以看到,当我们插入的数据的精度高于定义的值时,是会进行四舍五入的,并不会拦截。若四舍五入后的值超过了范围,也会进行拦截。C/C++中没有无符号的浮点数,但是MySQL中有,float(4, 2) unsigend的范围是[0, 99.99]

浮点数在计算机内部存储时,是先转化成二进制,再使用科学计数法存储的,科学计数法存储时会有符号位、指数位、精度部分。由于这两层转化的存在,对于精度过高的浮点数,可能会存在精度损失的问题

我们修改以下上面的表t3,使其能存放精度更高的浮点数


可以发现,此时就发生了精度损失。
double与float是类似的,只是精度更高,这里就不做过多赘述了。

decimal

decimal(m, d) [unsigned] : 定点数m指定长度,d表示小数点的位数

从上面我们可以看出float有一个问题,当数太多、小数点后数太多或整体数太大时,会出现精度损失。decimal与float是类似的,只是能够更好地保证数据的精度

字符串类型

char

char(L): 固定长度字符串,L是可以存储的长度,单位为字符,最大长度值可以为255


向这个表中插入一些数据

在MySQL中,char后面的数字是字符的个数,与大小无关。在utf8中,一个汉字占3字节,在gbk中,一个汉字占2字,普通的英文字符只占1字节。

char后面的数字最大是255,并且注意,指定了L并且建完表之后,就已经开辟了空间

varchar

varchar(L): 可变长度字符串,L表示字符长度,最大长度65535个字节

varchar是变长字符串。char(L)是L给多大就开多大,不管我们放入几个字符,长度都是L。varchar(L),这个L是上限,我们输入几个字符,字符串的长度就是多少。注意,varchar真正能放入几个字符,不仅仅与L有关,还与表的编码方式有关(因为varchar的L的最大值单位是字节,而char的L的最大值单位是字符) 
varchar长度可以指定为0到65535之间的值,但是varchar内部会有一个变量保存用了多少字节,一个变量用于保存能用多少字节,所以会有1-3个字节用于记录数据大小,所以说有效字节数是65532。具体是1个,2个,还是3个,会根据L来调整。
当我们的表的编码是utf8时,varchar(n)的参数n最大值是65532/3=21844[因为utf中,一个字符占用3个字节],如果编码是gbk,varchar(n)的参数n最大是65532/2=32766(因为gbk中,一个字符占用2字节)。

可以看到,超过6个字符就不行了
我们再来看一个奇怪的现象

当我们想将varchar设置成最大值时,MySQL会提示我们最大值是21845,但是当我们真正设置成21845却不行,甚至21844、21843都不行,这是为什么呢?
其实当我们把长度拉满时,会有3个字节来表示数据大小,MySQL之所以会提示21845,是因为他并没有将这3个字符去除。21844、21843不行,是因为t6这个表中,不仅仅只有name,还有一个int类型的变量,MySQL中65535字节表示的也是一行最多能有几个字节,而int会占用4个字节,所以只能65532。所以,建表时的其他字段也会影响varchar的长度。

char和varchar的比较

如何选择定长或变长字符串?

如果数据确定长度都一样,就使用定长(char),比如:身份证,手机号,md5
如果数据长度有变化,就使用变长(varchar), 比如:名字,地址,但是你要保证最长的能存的进去。定长的磁盘空间比较浪费,但是效率高。
变长的磁盘空间比较节省,但是效率低。
定长的意义是,直接开辟好对应的空间

变长的意义是,在不超过自定义范围的情况下,用多少,开辟多少。

日期和时间类型

常用的日期有如下3个:

  • date :日期 'yyyy-mm-dd' ,占用三字节
  • datetime 时间日期格式 'yyyy-mm-dd HH:ii:ss' 表示范围从 1000 到 9999 ,占用八字节
  • timestamp :时间戳,从1970年开始的 yyyy-mm-dd HH:ii:ss 格式和 datetime 完全一致,占用四字节

日期:年月日,时间:时分秒


当表中有时间戳时,不需要对这一列进行插入操作,当我们向表中插入、修改数据时,时间戳会自动更新(只是对插入、修改的这一行)

时间戳常用于评论区等

enum和set

  • enum是枚举类型,enum('选项1','选项2','选项3',...);,后面带的选项只能多选一
  • set是集合类型,set('选项值1','选项值2','选项值3', ...);,后面带的选项可以多选一或多选多


枚举类型、集合类型均只能插入选项,插入不是选项的值是会报错

枚举类型插入时除了可以插入枚举常量,还可以插入枚举常量的下标,下标从1开始

枚举类型和集合类型都是允许为空的

注意:NULL和''是不同的,NULL是没选,''是选了,只是没有选择其中的任何一项

集合类型同样可以使用数字来进行插入

这好像和上面的不一样吧?
因为集合类型的数字代表的是位图。1是0001,是代码,2是0010,是羽毛球,3是0011,是代码+羽毛球

enum和set的查找


查找时同样可以使用下标


当我们对set进行查找时,是严格匹配的,用数字查找同样是严格匹配的。若想要查找出所以包含羽毛球的,需要使用find_in_set函数

find_in_set(sub,str_list) :如果 sub 在 str_list 中,则返回下标;如果不在,返回0;str_list 用逗号分隔的字符串。


find_in_set是查询一个元素是否在集合当中,上面的表达式结果是1,表示的是'a'在集合'a,b,c'当中,并且下标是1

也可以同时查找符合多个条件的,如现在查找hobby既有代码的,又有羽毛球的,可以使用and,类似于&&,是逻辑与

数据类型对于表而言是一种天然的约束,将数据类型一定,未来表中插入的数据都是可预期的。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值