目录
数据类型
数值类型
tinyint类型
bit类型
float类型
decimal类型
字符类型
char类型
varchar类型
日期和时间类型
选择类型
表的约束
null
default
comment
zerofill
primary key
auto_increment
unique key
foreign key
数据类型
在MySQL中的数据类型与我们在学习语言上的数据类型大致差不多,只是换了一种说法而已
数值类型
tinyint类型
tinyint,smallint,mediumint,int和bigint都是大差不差的类型,只不过是大小不同而已,这里以tinyint类型作为例子演示;
在表中创建tinyint类型(默认是有符号类型)并插入一些数据来验证它的范围是否与上面表中的范围相同
当插入的数据不在tinyint类型(有符号)规定的:-128 ~ 127时,mysql直接报错拦截,不让我们进行插入无效的数据;反过来说,当数据成功插入时就证明数据是合法的,这就说明了数值类型本身是一种约束:倒逼使用者尽可能出入合法的数据,同时也保证了数据库数据的正确,合法性
而在语言上使用无效的数据时可能只是出现警告没有报错拦截,在程序运行时数据截断后再把数据储存起来,这时运行结果就不是我们所预期的;
bit类型
使用bit类型时要指明bit个数,不指明默认为1,bit个数范围【1,32】
在原有的表b1中创建bit类型表示性别(0表示女,1表示男)
创建完表插入数据后,把表的数据打印出来是发现gender数据不显示?因为bit类型显示时是按照ascall码形式显示的,想要转化成0 1就要对gender修改显示方式
证明是按ascall码显示的
float类型
使用float要指明两个数:第一个数m指定数据总长度,第二个数d指定小数位精度
例如:float(4,2)表示的范围是-99.99 ~ 99.99,MySQL在保存值时会进行四舍五入(如果指明无符号的话范围是0~99.99,对半砍一半)
decimal类型
与float类型类似,但是float类型定义出的精度d太大(d最大为7位)时会精度丢失,而decimal类型精度d相对float来说会比较大一点(d最大为30位)
对精度要求高的情况下推荐使用decimal类型
字符类型
char类型
char类型是固定字符串,使用时要定义出长度大小(最大为255),注意这里单位是字符,不是C/C++的单位为字节,所以储存汉字时按照汉字个数定义出的长度大小即可,不用再去计算字节数了(utf8字符集时:1字符 = 3字节)
varchar类型
varchar类型是可变长字符串,使用时也是一样要给出长度大小,单位是字节,最大字节数为65535字节,使用utf8字符集编码时要进行转化为字符,即最大字符数是:65535 / 3 = 21845字符
但是在实验时创建长度为21845的varchar时mysql不让我创建了,明明上面mysql提示最大字符数与自己的计算结果是一样的,为什么不然我创建?
原因是varchar类型底层在实现时与C++的string类似:有计数器与空间大小来记录有多少字节,总的空间数是多少,根据使用字符数大小给你开辟对应大小的空间,所以本身需要1~3字节来储存这些管理数据,按照最大来计算:(65535 - 3) / 3 = 21844字符,但还是不让我创建啊!
因为还有id字段的影响,varchar类型的最大字节数表示的是一行的最大大小:此时还要在减去4字节才是实际创建varchar的最大字节数!
关于char与varchar的对比
使用字符类型选择时:
- 如果数据确定长度都一样,就使用定长(char),比如:身份证,手机号,md5
- 如果数据长度有变化,就使用变长(varchar), 比如:名字,地址,但是你要保证最长的能存的进去
- 定长的磁盘空间比较浪费,但是效率高
- 变长的磁盘空间比较节省,但是效率低
- 定长的意义是,直接开辟好对应的空间
- 变长的意义是,在不超过自定义范围的情况下,用多少,开辟多少
日期和时间类型
- date :日期 'yyyy-mm-dd' ,占用三字节
- datetime 时间日期格式 'yyyy-mm-dd HH:ii:ss' 表示范围从 1000 到 9999 ,占用八字节
- timestamp :时间戳,添加数据时自动补齐当前时间,与datetime 格式完全一致,占用四字节
date使用:通常是用来记录个人生日信息,datetime使用:通常记录你第一次到公司工作的时间,方便计算工龄与发放工资;而timestamp使用:常见的是用来记录网络论坛上用户评论的时间
选择类型
使用enum和set可以填写多个数据,在插入数据时选择数据进行插入,但是enum是只能选择一个,而set可以选择多个
使用场景:创建调查表votes调查用户的爱好
选择时可以使用枚举的数据,enum可以选择从下标1开始,用数字进行选择;而set想要用数字选择需要进行计算,因为它是按照位图的结构来管理数据的:想要选择前两个爱好输入的数字是3,而不是123,因为3是:011 -> 低位的1代表的是选择乒乓球,一次类推...
有这样一个需求:想要在全部数据中找到所有爱好包含是‘乒乓球’的用户时,要使用函数find_in_set函数
如果要挑选的是所有人的爱好中包含乒乓球和羽毛球的呢? 要使用and连接起来
表的约束
数据类型本身也是一种约束:但你插入的数据不合法时,mysql直接报错拦截你不然进行插入;这样做有两种好处:保证数据库中数据的正确,合法性;倒逼程序员插入正确的操作;而在表中也同样存在约束,mysql提供了约束使用表的操作,如:null,default,comment...
null
空属性null:mysql上共有两种表达:null 和 not null,字段为null的值是不参与计算的
建表时填写的字段不设置默认null,也就是该字段插入数据时可以不填写;但如果设置了not null就代表:插入数据时该字段必须填写的是合法的数据,不能是null!
字段grade设置了not null,插入数据时不带该字段,出现的是不同的报错:这与下面的default有关
default
默认值default:某一种数据会经常性的出现某个具体的值,可以在一开始就指定好,在需要真实数据的时候,用户可以选择性的使用默认值
把上面演示的表中的字段gender添加默认值上去
插入数据看看有什么不同
字段gender设置默认值default,插入数据时不带该字段gender使用默认值,如果有进行插入数据,不管是null还是合法的数据都能插入;在上面null中对字段设置了null,插入数据时不带该数据后报错,原因是没有设置默认值;两者是相互补充的关系,但通常不一起使用
comment
列描述comment,没有实际含义,专门用来描述字段,会根据表创建语句保存,用来给程序员或DBA来进行了解;使用 desc tablename 看不到,要使用 show create table tablename \G 显示具体信息才能观察到
zerofill
创建一个表,里面有两个相同的字段int:一个有符号另一个无符号;创建完后使用 desc 查看表时发现在类型一列中多了用括号扩起来的数字,这时什么意思呢?
插入数据后查看数据,并在字段b中添加zerofill后,再次查看数据
此时我们发现:字段b前有9个0,加上1就刚好是10位数,这不就是括号里面的值吗!
所以:设置 zerofill 是用来进行对字段进行格式化输出,至于说 int 为什么多了一位,是因为它是有符号的整数,多了一位符号位; 解决了 zerofill 的问题,那为什么b是10位而不是20位呢?原因是:int 最大值是42亿多,需要用10位数来表示这个最大值
当然我们也可以自己来设置这个值;当插入的数据的个数大于设置的值则不用0来填充,用自己的数值来表示,我们也可以顺便来验证下填充的0是否会对查询数据有影响
primary key
主键primary key 用来唯一的约束该字段里面的数据,不能重复,不能为空,一张表中最多只能有一个主键;主键所在的行通常是整数类型,设置了 primary key 的字段 null 也被设置
如果不要主键了,要进行 drop 删除主键
如果后悔了,想把主键添加到字段id 上来的话,必须先把之前重复的数据删除才能添加
一个表中只能有一个主键,但主键不仅只能被一个字段使用,还可以与其它字段组合,称为复合主键
例如:在学校系统中,学生在同一个学期不能重复选择相同的课程修学分(除了挂科重考)
auto_increment
自增长auto_increment:字段设置自增长使用时自动触发,从当前表中的最大值+1作为新的值,通常与主键primary key 一起使用,成为逻辑主键
自增长的特点:
- 任何一个字段要做自增长,前提是本身是一个索引(key一栏有值)
- 自增长字段必须是整数
- 一张表最多只能有一个自增长
查看自增长auto_increment 的值有两种方式
unique key
唯一键unique key:用来解决表中有多个字段需要唯一性约束的问题;咋一听与主键primary key类似,但还是有区别的
唯一键 | 主键 |
---|---|
表中可以存在多个 | 表中只能存在一个 |
可以允许字段为空 | 不允许字段为空 |
保证业务逻辑的唯一性 | 标识字段唯一性 |
虽然有区别,但两者经常一起使用,相互补充!主键只能保证一个字段的唯一性,但是一张表中不可能其它字段就一定不用保证唯一性了,如:一个学生有学号,名字,电话号码,qq号...
如果只设置id是主键,插入时如果粗心大意,把不同人的电话号码填写成一个,那里下次我要通过电话号码找人时就会出现冲突
此时使用唯一键来解决:填入相同的电话号码时就不让你插入
foreign key
外键foreign key 用于定义主表与从表之间的关系:一般先定义主表(主表要与从表产生关联的字段必须有primary key或者unique key),再定义从表(在里面定义外键约束):主表插入数据时受关联的字段必须在从表中存在(从表删除数据时受关联的字段在主表中不存在)
比如有两张表:一张表class 记录班级的各种信息,包括班级编号,名字,一张表student 记录学生的各种信息,包括学生号,姓名,电话,年级;如果我们不添加外键的形式,正常实现插入数据:会发现如果 class表中没有id为101的班级,而在 student表中却发现有学生的grade(id)是101的班级,那这不是与 class表中出现冲突吗?相反把本来有id为101的班级数据从 class表中删除,此时 student表中id为101的学生不就又是冲突的吗!所以解决这个问题,就需要外键foreign key来解决:设置时class为主表,student为从表
如果想在 student表中插入数据为 grade为101时,class表中找不到id为101的数据时插入失败;class表中要想删除id为101的数据,就要等 student表中所有grade=101数据删除后才能删除
外键的使用:在设计表时理解好表与表之间是否存在相关联系的逻辑关系,是否会在插入数据时发生逻辑上的矛盾或者错误
以上便是全部内容,有问题欢迎在评论区指正,感谢观看!