mysql数据类型(主要讲tinyint int varchar)
1 整形字段 tinyint(1字节)、smallint(2字节)、mediumint(3字节)、int(4)和bigint(8)
tinyint(1)中的1到底是啥意思 int(11)中的11又到底是什么?
我先创建一张表来实战一下
CREATE TABLE t1 (
a tinyint(1) not null DEFAULT 0 comment “整形字段a”
) engine=InnoDB CHARSET=utf8mb4;
先说个前提:一张表最多存储的字节数是65535个
想一下,是只能存储0和1吗?当时不是的,怎么证明呢?接下来操作一下就知道了
此时咱们来插入一条记录
我定义的是有符号的,可以存储-128到127,说明tinyint(1)中的1是代表默认长度是1,占用1个字节,能存储的大小和长度是否是1没有任何关系,比如是tiny(3),长度小于3的时候前面会用0做补充,接下来继续看,我再创建一张表
此时我再插入一条数据
看明白没,tinyint(3)到底是什么意思,清楚了吧,3不代表只能存储长度为3,对于整形来说,他能存储多少和括号里的数字没有任何关系,只和当前类型多占用的字节有关系,tinyint有符号可以存储的范围是-128到127,无符号下可以存储0-255, 懂?
2
char和varchar(重要)
咱们在业务中建立mysql表的时候,用的最多的是varchar,varchar可以存储的大小和字符集密切相关的,char(10) varchar(10)到底是什么意思?是占用10个字节还是10个字符,在mysql4.0之前是占用10个字节,4.0之后是字符,接下来我创建一个字符集是uft8mb4的一张表
注意:此时char(255) 是代表在utf8mb4字符集下可以存储的字符数是255,不管是英文还是中文可以存储255个,假如存储了255个中文字符,我们知道在utf8mb4一个中文(我说的是中文)字符占用4(我是按照最大说的,实际上中文占3个 和utf8一样,有些表情字符只能是uft8b4,占4个字符)个字节,那么此时char类型存储的字节(我说的字节不是字符哈,注意)数是
255乘4=1020个字节。char类型最大可以存储多少字符呢?是字符哈,看图
看到没char类型最大可以存储255个?可以存储255个字符和字符集没啥关系
重点来了,varchar(10)是啥意思?
他代表的意思是可以存储10个字符,超过10个字符就会报错,不信的话再创建一张表来看下
此时再插入一个会怎么样
我没有骗你吧,varchar最多可存储10个字符,那么此时占用了多少字节呢?
有人说了,应该是10 乘4=40答案是错误的!!!!!
由于mysql中定义varchar的时候,有时间自己看下mysql默认的行格式,我自己总结的:如果表中你定义了m个varchar类型的字段,就用m/8 向上取整,比如定义了一个就会占用1/8=2个字节空间大小(此时说的是定义default null允许为空的情况下来说的),上图中定义了not null,行格式中null标志位就不占用空间了,由于varchar是可变长的字段类型,存储长度不够10个会用空格来补充,由于可变类型定义的字段varchar(10)括号中的数字和字符集占用的字节数做乘法,如果小于255会用1个字节来表示长度,大于255会用2个字节表示长度,所以这个列子所占用的空间为10乘4+1=15个字节,如果把a字段定义为default null允许为空,那么多占用的空间大小为10乘4+1/8+1=16个字节,如果此时定义的a的类型为varchar(70),此时70*4=280>255此时需要用2个字节大小来存储长度,此时占用的空间为70乘4 + 1/8(default null) + 2=280+1 +2=283字节,不信咱们创建一个最简单的例子
根据刚才说的我们来计算下,此时一个字符可以占用一个字节,由于最大为65535,那么计算方式是不是应该这样(此时定义了字段not null,所以null标志位不占空间),用65535-2-n=0,此时n为65533,咱们来看下是不是这样
此时我再加一个字符
此时超了
如果我此时定义为default null看看最大可以存储多少?
我们来计算下,由于允许为空,所以需要占用的字节数应该是定义了varchar的数量/8向上取整,也就是1/8=1,所以n此时最大可以存储
65535-1-2-n=0 ,此时n=65532,看看是不是这样
看到没,确实是这样吧,没撒谎,实践来验证
如果知道这个了,下面来一个题,这个实际存储的字节数是多少?
题目:假设有个VARCHAR(64) CHARSET utf8mb4列,存储了中国cn这个字符串。
那你猜一猜,MySQL存储时用了多少字节?
A:4 Bytes
B:5 Bytes
C:8 Bytes
D:9 Bytes
E:10 Bytes
F:10.125 Bytes
G:11 Bytes
H:12 Bytes
I:12.125 Bytes
K:13 Bytes
答:由于64乘4=256>=256所以,需要2字节来存储它的大小,由于只定义了一个varchar,并且字段允许为空,那么还需要1/8=1个字节记录null标志位,utf8mb4下,中文实际一个字符是3个字节,存储中国二个字就占用了3 乘2=6个字节,cn这二个字符总共占用了2个字节,所以一共占用的大小是
6 + 2 + 2 + 1=11
或者
6+2+2+1/8=10.125所以答案是f和g
这回懂了吧
再来一个例子,请自己思考一下,为什么是这样,多看看前面我说的,你就明白了
最后一个作为思考
CREATE TABLE t11 (
id int,
a VARCHAR(100) DEFAULT NULL,
b VARCHAR(100) DEFAULT NULL,
c VARCHAR(100) DEFAULT NULL,
d VARCHAR(100) DEFAULT NULL,
e VARCHAR(100) DEFAULT NULL,
f VARCHAR(100) DEFAULT NULL,
g VARCHAR(100) DEFAULT NULL,
h VARCHAR(100) DEFAULT NULL,
i VARCHAR(n) DEFAULT NULL
) CHARSET=utf8;
这个时候n最大为多少呢,注意是utf8字符集
答案先告诉你是21037,这个自己考虑一下吧
总结:1、整形字段比如tinyint(3)中的3和能存储多大值没有关系,这个只是默认长度是3,长度没有到3前面用0来补齐
2、char(n)类型的字段是固定的,即使内容没有达到字符长度用空格补充,实际所占用的空间和字符集有关系,utf8下占用n乘3个字节,utf8mb4下占用n 乘4个字节
3、定义varchar(n)分二种,允许为空,和不允许为空
当定义字段允许为空的情况下,所占用的大小和字符集有关,null标志位有关,和定义了几个varchar有关,如果此时为utf8mb4的情况下,n乘4<=255,那么总共占用大小为(在定义字段的时候)n乘4+1 + 定义的varchar数量/8
如果n 乘4>255占用空间大小为n 乘 4 + 2 + 定义的varchar数量/8
如果此时定义不允许为空的情况下,并且字符集为uft8mb4的时候,并且
n 乘4<=255占用的空间大小为n乘4+1,如果n乘4>255的时候占用大小为
n 乘4+2