都知道C语言有int(4个字节)、char(1个字节)…
这些类型可不是随便用的,,我们要考虑在某个场景用它是否合适,会不会越界。MySQL中也是一样的,也需要不同的场景需要不同的类型。
下面这张表是MySQL的数据类型分类:
下面我们来具体看看这些类型的具体应用和如何应用:
数值类型
- tinyint类型
从表中我们可以观察到tinyint类型的范围是-128~127
我们先创建一个表:
create table tt1(num tinyint);
然后插入一个66,再插入一个128,看能插进去几条数据
发现只有一条数据,这是因为128越界了,不能插入。所以在使用数据类型的时候,我们一定要注意看是否会越界。
unsigned是无符号的意思,现在建一个无符号的表我们向里边插入数据:
create table tt2 (num tinyint unsigned);
无符号的tinyint的范围是(0~255),所以-5是不可以插入tt2的
没有umsigned默认是有符号的
-
bit类型
语法:
bit[(M)] : 位字段类型。M表示每个值的位数,范围从1到64。如果M被忽略,默认为1。
例:
我们会发现一个很奇怪的现象,为什么a的10没有显示出来呢?
那是因为比特字段在显示时,是按照ASCII码对应的值显示的,而10没有对应的ASCII的值。
我们插入一个66看看:
当然bit也存在越界问题。 -
float类型
语法:
float[(m, d)] [unsigned] : M指定显示长度,d指定小数位数,占用空间4个字节
例:float(4,2) 它的范围是-99.99~99.99
float也存在有符号和无符号。
如果是create table tt5(id int, salary float(4,2) unsigned)
则输入数据(1,-99.992)是错误的。
无符号的范围是从0开始的。 -
decimal类型
语法:
decimal(m, d) [unsigned] : 定点数m指定长度,d表示小数点的位数
decimal和float很像,但它两的区别就在于精度不同,decimal的精度比float更准确些。
例:
字符串类型
-
char类型
语法:
char(L): 固定长度字符串,L是可以存储的长度,单位为字符(字母/汉字),最大长度值可以为255
例:
如果name char(256) 则是错误的
-
varchar类型
语法:
varchar(L): 可变长度字符串,L表示字符长度,最大长度65535个字节
例:
虽说varhar的最大长度是65535,但是有1-2个字节是用来记录数据大小的,所以有效的字节是65533。
编码不同,varchar(L)里的最大值L是不同的。
utf8中,一个字符占3个字节,所以L = 65533/3 = 21844
gbk编码中一个字符占2个字节,所以L = 65533 / 2 = 32766
我们可以验证一下:
那到底什么时候用定长?什么时候用变长?
我们可以先来把char和varchar进行比较:
总结:
- 如果数据长度都一样,就用char,比如身份证号、手机号
- 如果数据长度不一样,就用varchar,比如名字、地址,但要保证不越界
- 定长的磁盘空间比较浪费,但效率高
- 变长的磁盘空间比较节省,但效率低
- 日期和时间类型
- datetime 时间日期格式 ‘yyyy-mm-dd HH:ii:ss’ 表示范围从1000到9999,占用八字节
- date:日期 ‘yyyy-mm-dd’,占用三字节
- timestamp:时间戳,从1970年开始的 yyyy-mm-dd HH:ii:ss格式和datetime完全一致,占用四字节
例:
如果更新数据的话,时间戳也会更新为当前时间的
-
enum和set
enum:枚举,单选类型
语法:
enum(‘选项1’, ‘选项2’, ‘选项3’…)set:集合,多选类型
语法:
set(‘选项1’, ‘选项2’, ‘选项3’…)
例:建一个兴趣爱好调查表votes,比如(游泳、跳舞、弹吉他、滑雪、冲浪)中选择(可以多选),(男、女)【单选】
create table votes(
-> name varchar(20),
-> hobby set('游泳','跳舞','弹吉他','滑雪','冲浪'),
-> gender enum('男','女')
-> );
插入数据:
insert into votes values('calm','跳舞,滑雪,游泳','女');
insert into votes values('lilei','冲浪,弹吉他',1);
insert into votes values('jane','冲浪,跳舞,弹吉他','2');
insert into votes values('helon','滑雪','男');
搜索gender=1的爱好者:
select * from votes where gender=1;
enum默认是从1开始
如果我们想要查询所有喜欢跳舞的人,就需要使用集合查询使用find_ in_ set函数
语法:
find_in_set(sub,str_list) :如果 sub 在 str_list 中,则返回下标;如果不在,返回0; str_list 用逗号分隔的字符串。
例:查询所有喜欢跳舞的人
select * from votes where find_in_set('跳舞',hobby);