MySQL数据类型

1.数据类型分类:

2.数值类型:位类型,布尔类型,整数类型,浮点数类型

下面是整形:

上面这么多类型其实都叫做整数类型,它们所占字节数大小是不一样的。默认是有符号类型的,取值范围也和C/C++学习的对应的整数范围是一样的。如果tinyint、samllint后面加 unsigned 就代表是无符号类型。

2.1 tinyint类型:

正常范围都可以插入,超过之后便不允许了。

在MySQL中,整型可以指定是有符号的和无符号的,默认是有符号的。

可以通过UNSIGNED来说明某个字段是无符号的

如果在C/C++中向一个char类型插入比它取值范围还大的数据 , 如char a=1234567;此时会截断然后放进去。

如果我们向mysql特定的类型中插入不合法的数据,mysql一般都是直接拦截我们,不让我们做对应的操作! MySQL必须保证插入数据的完整性,一旦截断,那mysql中有些是成功插入的有些是截断后插入的,作为用户来讲是无法信任mysql中数据的。

反过来,如果我们已经有数据被成功插入到mysql中,一定是插入的时候合法的!

注意:尽量不使用unsigned,对于int类型可能存放不下的数据,int unsigned同样可能存放不下,与其如此,还不如设计时,将int类型提升为bigint类型。

2.2 bit类型:

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

位类型,M表示比特位的位数。比如一个比特位取值范围0-1,两个比特位取值范围0-3,四个比特位取值范围0-15

原因就是在于当前这个online是位类型,位类型在显示的时候通常是按照ASCLL码值得形式显示的。只不过当前在online插入得值是0,1在ASCLL码值中是属于不可显示的,所以这里什么都看不到。

如果想要看见,可以让online按照16进制方案显示:select id,hex(online) from t3;

那到底是不是这样的呢,我们把这个online类型改一下,插入65,97,看到显示的确实就是ASCLL码中的A,a,而前面插入的0,1就是不会显示因为它是在ASCLL码中是不可显示的。

2.3浮点数类型:

2.3.1 float:

语法:

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

在定义的时候可以在列字段后面带上float类型,该列就会变成浮点数类型。而浮点数类型我们可以 选择性的携带,M代表的是浮点数数字个数的总位数,d代表小数点之后数字的位数。

因为目前float后面我们没带unsigned,所以既可以插入正数也可以插入负数。而且float M为4表示插入浮点数总位数是4,d为2表示精度位数是2个。

float(4,2)表示的范围是-99.99 ~ 99.99

实际上在进行浮点数存储 的时候,如果要求2位精度,但是你传入了更多的位的精度,MySQL在保存值时会进行四舍五入 将数据进行存储。

上面是有符号的,下面定义无符号的

虽然是无符号的但是我们发现这里上限还是99.99,并且插入负数根本不行,换句话说将float定义成无符号类型,直接把负数全部砍掉。直接变成了0-上限。同时也有精度不够补0,够了也要做四舍五入。

最后一点浮点数在存的时候是有精度损失的,可以看到我要存的和实际上存的不一样,从这就能看出来浮点数在存的时候是有可能精度损失的。

2.3.2 decimal:

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

decima也是MySQL当中的一个浮点数类型,也可以指定长度和小数点的位数和float和double一样。它的使用和float一模一样,也有精度不够补0,够了四舍五入。float经过验证发现它是有精度损失的,但只decimal可以有效的规避这一点。

可以对比发现虽然float精度设为8但是实际上存的时候已经和插入数据不一样了。float类型往往在精度过大或者整体数字过大时会帮我们做一些优化策略,但是decimal不会,它能够完完全全让数据怎么存就怎么取。所以未来你的场景对精度有要求就用decimal,精度要求并不高就用float。


3.字符串类型:

3.1 char:

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

首先要说的是在utf8编码中一个汉字占3个字节的,gbk编码一个汉字占2个字节。

这里中国是占了6个字节依旧可以表里面做插入,而char类型中长度单位为字符。 这里要特别说明一下,MySQL中的字符和C/C++中的字符概念是不一样的,以前语言上的字符,一个字符对应一个字节,而在MySQL中的字符真的代表一种符号,要么是1234、要么abcd、要么就是中文汉字,一个汉字就是一个字符。

3.2 varchar:

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

varchar是一个变长字符串,下面我们看看它这个类型对应边界特性以及约束体现在哪里

当前我们定义varchar括号里面是5,并且允许我们进行字符式的插入,每一个汉字都是一个字符。我们最多可以插入5个字符,然后多插字符就不让插了。就这就varchar 后面括号带数字的意义。

char与varchar区别:

char是固定长度字符串,类似于C/C++中定义一个数组,比如定义一个char(6) 就代表字符个数是6个字符也就是18个字节。至于当前你用了多少我不管。反正你要6我就给你6个字符的空间,有可能你只用了1个,但我依旧给你6个。也就是不管你用没用到那么多空间,只要你要了我都给你那么大的空间。

但是varchar不一样,这个L你定义多大,这个数字表示的是该字符串空间的上限!比如说varchar(6),L是6,实际上当我们在正常使用的时候,你可能只用了一个,那varchar只会给你分配保存一个字符的空间。换句话说你用多少给你多少,但是上限是L。 换言之,我们字符的上限和我们有多少用多少并不冲突。

关于varchar(len),len到底是多大,这个len值,和表的编码密切相关:

varchar字节长度为0到65535之间,但这个变长字符串里面一定要有一点空间用来保存实际用了多少字符,所以有1 - 3 个字节用于记录实际用了多少字符的 数据大小,varchar尽可能节省空间,所以它会根据实际字符的个数来动态调整用几个字节来表示有效字符的个数。假设未来会把varchar字符数写满,所以最终一定要三个字节来记录数据大小。所以说有效字节数是65532。

当我们的表的编码是utf8时,varchar(n)的参数n最大值65532/3=21844因为utf中,一个字符占用3个字节,如果编码是gbk,varchar(n)的参数n最大是65532/2=32766(因为gbk中,一个字符占用2字节)

当前是len是21845,是不让我们建表的,换成21844就可以了。这就证明了varchar字符个数不能超过21845,只能在21844包括21844以内。

如果是一行65535是可以的,但是表有两行呢:

前面我们改表的时候,它提醒max=21845,但是我们换成21845还是不行,是因为需要几个字节计数。再换成21844也还是不行,原因在于t5里面有一个id,它报错原因是一行大小太大了,其实MySQL这个65535这个值也代表一行MySQL当中的数据,表示一行一行存的,可以理解为表共享一行空间,只能再改小一点才行。

3.3 char 与 varchar比较:

共同点:都能保存字符串 ,都有上限。但char是定长的,varchar是变长的,char一次把空间分配好;varchar用多少给多少,因为里面有字节保存有效字符个数。

这里只用一个字节就能保存有效字符个数

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

如果数据确定长度都一样,就使用定长(char),比如:身份证,手机号,md5

如果数据长度有变化,就使用变长(varchar), 比如:名字,地址,但是你要保证最长的能存的进去。

定长的磁盘空间比较浪费,但是效率高。

变长的磁盘空间比较节省,但是效率低。

定长的意义是,直接开辟好对应的空间

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


4.日期和时间类:

常用日期有如下三个:

date :日期 'yyyy-mm-dd' (年-月-日),占用三字节

datetime :时间日期格式 'yyyy-mm-dd HH:ii:ss' (年-月-日 时-分-秒)表示范围从 1000 到 9999 ,占用八字节

timestamp :时间戳,从1970年开始的 yyyy-mm-dd HH:ii:ss 格式和 datetime 完全一致,占用四字节

date、datetime定义好允许我们自己向表中插入,而timestamp是时间戳 ,时间戳会自动变化。不需要我们自己做任何操作。也就是说这个表中只要有时间戳,只要对这一条记录插入或者更改时,这个时间戳会被自动更新到最新时间。


5.enum和set:

语法:

enum:枚举,"单选"类型;

enum('选项1', '选项2', '选项3',...);

MySQL允许我们设置表结构,在表结构中设置枚举类型。enum后面可以带一些特定的选项。这些选项一定是多选一,单选!做问卷调查有一个选项问你是男还是女,你只能选一个。

set:集合,"多选"类型;

set('选项值1', '选项值2', '选项值3', ...);

set也是一样,允许在建表的时候创建集合类型,集合类型中可以设定特定的n多个选项值,这些选项值在设定的时候多选、单选都行,如问卷调查问你的爱好给你好几个选项,你可以选一个也可以选多个。

我们插入的只能是属于enum枚举类型给我提供约束,换句话说插入时只能插入枚举的类型,不允许插入除该枚举类型外其他任何字符。

下面可以看到插入数字1、2可以插入,其他的都不能插入了。换句话说,当enum枚举类型在插入的时候,可以直接写这个枚举限定的常量,也可以写对应常量的下标,注意这个数字下标从1开始,有几个就到几,分别代表第一个枚举值第二个枚举值等。

下面在看看set集合我们发现,set不允许插入不存在的类型。插入时可以单插入,也可以以逗号为分隔符多插入。值必须是定义里的合法选项,且 SET用英文逗号、选项之间不能有空格。

当不向enum和set中插入时,默认为NULL。当前我们向set中插入一个0,什么都没有显示,其实这里并不是没用。

NULL 和 ' ' 是不一样的。NULL真的表示什么都没有, ' '表示有东西只不过这东西是空串,所以它们俩个是不一样的。

数字插入规则:

目前这里有5个爱好,在集合中我们把它想象成5个比特位 00000 ,这里我们从右到左表示从低比特位到高比特位。

插入1的时候 00000 -> 00001 ,这个比特位的位置代表是代码这个爱好,这个比特位的内容为0为1代表也没有这个爱好,1代表有代码这个爱好,0就代表没有。这就是我们刚才插入1的时候,显示的是代码的爱好

插入2的时候 00000 -> 00010 ,第二个比特位置为1表示有羽毛球这个爱好

比如插入的是7 00000 -> 00111 ,表示当前表中低三个爱好都有,所以会显示出前三个爱好

所以,当我们在向一个set集合中插入的时候,这个数字代表的是位图,集合中有几个类型就有几个比特位,比特位从低向高依次代表set类型中从左向右。比特位的位置代表是那个类型,比特位为0为1代表是否是有这个类型。

注意:enum枚举中插入数字代表的是下标,set集合中插入数字代表的是位图。

enum和set的查找如何做呢?

enum:

set:

此时确实能把爱好是代码的人筛选出来了,但是呢有的人有多种爱好里面也有代码,但是这里筛选的时候把爱好只有代码的筛选出来了。我想要的不是爱好只有代码的,我要的是爱好有代码的。

那想只要有就给我筛选出来怎么做呢?

集合查询使用find_ in_ set函数:

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

find_in_set能够在一个集合中查找某一个元素是否存在,存在就返回对应的下标。其次它查找的过程是判断一个元素是否在集合中而不是判断相等的。

set这里查找爱好是代码用严格匹配,爱好有代码就可以用find_in_set

那现在要求爱好里有代码和蓝球怎么做呢?

我们where条件筛选和C/C++一样,相当于一种条件判断,里面可以有一个函数所对应的得到的结果,也可以把多种函数对应的结果级联起来,要求两个结果同时满足,就可以如下做,这里的and就相当于逻辑与。

相关推荐
蓝胖的四次元口袋2 小时前
Redis知识梳理(1)
数据库·redis·缓存
夜雪一千2 小时前
MySQL 数据加密实战:从传输、存储到字段级加密,分清场景不踩坑
数据库·mysql
wefg13 小时前
【Redis】C++ 自定义客户端
数据库·redis·缓存
这个DBA有点耶3 小时前
为什么UPDATE比SELECT危险得多?锁范围等于扫描行数
数据库·架构·代码规范
天国梦3 小时前
国密门禁品牌怎么选?2026年最新3个避坑要点
运维·服务器·数据库·python
DB哥讲数据库4 小时前
【达梦数据库安装教程】超详细图文讲解-附达梦安装包
数据库·oracle
Hoxy.R4 小时前
【金仓数据库产品体验官】KingbaseES V9R2C16 坏块检测与修复完整测试流程
数据库
高级程序源5 小时前
SSM仓储管理系统31582-计算机课程设计、毕业设计
vue.js·python·mysql·小程序·flask·课程设计
PC2005-cloud5 小时前
MySQL学习笔记:GTID 主从复制,从原理到实践,告别传统 Binlog+Position 的痛点
笔记·学习·mysql