对于MySQL数据库,笔者在之前的一篇文章,详细的介绍了一些基础的语法:比如:最常见的MySQL语句的增删改查+数据库的创建+where语句/order by语句/limit分页等语法,那么感兴趣的各位老铁,可以观看一下:MySQL数据库中的增删查改(MySQL最核心,工作中最常用的部分),原文链接为:https://blog.csdn.net/weixin_64308540/article/details/129698506?spm=1001.2014.3001.5501
那么,接下来,我们便开始进入今日的主题吧!!
数据库约束:
所谓的约束,就是数据库针对里面的数据,能写啥?所给出的一组检验规则!总不能让你往数据库里面随便乱写吧!!因此,约束:就是为了提高效率,提高准确性,让数据库这个软件集成一个针对数据进行校验的功能!
not null |
不为空,必填项 |
unique |
让列的值唯一,不能和别的列重复 |
default |
默认值 |
primary key |
主键,主要用来表示这一条数据的身份标识 |
foreign key |
外键,两张表之间的一个关联 |
check |
在MySQL5.7版本不支持,写了不支持,但是没有实际效果 |
对于上述的几个限制条件,那么,接下来,我们便会一一展示!!
当我们的数据没有约束的时候,可以随便插入(null)
给一个现有的表加约束比较麻烦!!虽然也可以,但是比较麻烦!alter table(修改表结构)用起来比较麻烦(支持的功能比较多),所以我们在MySQL中很少使用,当然,感兴趣的各位老铁,可以移步其他博客欣赏一下再回来!!尴尬!!
我们大部分会将一个已经存在的表(需要定义约束)进行删除,在重新定义!!尴尬!
就比如:定义约束:
create table student(id int not null,name varchar(20) not null);
当我们查询student表的表结构时:
desc student;
根据上面的结果,我们发现:Null的那一列变为了NO,对于正常的不加not null约束条件的时候已经发生了变化!!不加not null约束的时候,Null的那一列是YES,因此这就是差别!!
当我们进行插入数据的时候:
insert into student values(1,'张三');
因为插入的两个列均不为null,所以成功插入!
但是,当我们插入的数据id/name 有一行为null 的时候,就会插入失败!!
insert into student values(2,null);
insert into student values(null,'李四');
根据上述的两个案列的运行结果,我们可以看出not null限制了插入的数据不能为空!!
当我们插入的数据,有时候需要确保唯一,比如,,在一个学校里面,每个学生都有着自己的唯一的一个学号,肯定不会有重复的数据!因此,在这个情况下,就需要我们对插入的数据进行限制(unique)
当我们使用unique的时候,在进行插入/修改数据的时候,会先进行查询,先看看有没有该数据:
若存在该数据,则插入失败,如果不存在该数据,则插入成功!!
create table java_stundet(id int unique,name varchar(20));
当我们查询该表的表结构……
desc java_stundet;
当我们进行插入数据:
insert into java_stundet values(1,'张三');
成功的插入!
查询此时该表中的所以数据!
select * from java_stundet;
根据此时的结果,我们也可以看出成功的插入了!
当我们再次插入:
insert into java_stundet values(1,'李四');
这个插入语句没有任何问题!!
但是,根据结果显示,插入失败了!!
这个主要的原因就是使用了unique ,来确保id是唯一的!!
Duplicate |
重复的 |
entry |
入口,条目 |
在这个插入的过程中,数据库是怎么知道某数据已经存在(unique修饰的数据)的呢??
其实这个是数据库在插入之前进行查询了一下!只不过这个查询我们不知道而已!!
对于设置默认值也是一个经常用的语法!
默认值是insert指定列插入的时候,其他未被指定到的列就是按照默认值来填充的!
create table java_study(id int,name varchar(20) default '无名氏');
我们可以通过查看表结构来得出区别!
desc java_study;
当我们进行插入数据的时候,指定插入id这一列,对name这一列不进行插入!!
insert into java_study(id) values(1);
那么,我们来看一下此时该表中的数据!!
select * from java_study;
根据代码的运行结果我们可以看出:我们没有对name这一列进行插入,但是,仍然有着'无名氏'的数据!!这就是我们的default设置默认值起到的效果!!
对于主键:是一条记录在表中的“身份标识”,所谓的“身份标识”是用来区分这条数据和其他数据的关键指标!比如:手机号码,身份证,学号……这也是我们要求唯一,并且不能为空的数据!
因此:主键:primary key=unique+ not null !
在MySQL中,要求表里面只能有一个主键,创建主键的时候,需要有一个列作为主键(绝大部分,常见),也可以使用多个列作为主键(复合主键,很少见)!
create table java_mysql(id int primary key,name varchar(20));
当我们查看该表的表结构的时候,我们可以看出……
desc java_mysql;
当然,我们在插入的时候,仍然要求id列确保唯一!!
insert into java_mysql values(1,'张三');
第一次插入id=1,插入成功!
当我们再次插入id=1的时候:
insert into java_mysql values(1,'李四');
出现了重复插入的警告!!所以,主键是唯一的!不能为空的!!
当然,有了主键能够帮助我们节省不少活,但是,由于粗心大意啥的,导致忘了写主键了,那么,岂不是每次都得报错?然后在重写一次??为了避免这个麻烦,我们有了自增主键的这个语法!!
所谓的自增主键,就是在插入数据的时候,将主键的这个列的数据不写,或者写为null,MySQL会自己增加一个唯一并且不为空的数据!!
create table java_student(id int primary key auto_increment,name varchar(20));
当我们查询该表的表结构的时候……
desc java_student;
细心的各位老铁就会发现很大的区别!
给自增主键插入数据的时候,可以手动指定一个值,也可以让MySQL自己分配,如果让MySQL自己分配,就在insert插入数据的时候,将id设置为null即可!!
insert into java_student values(null,'张三');
insert into java_student values(null,'李四');
在insert插入数据的时候,自增主键的那一列写了null,不是指:插入null,是指,让MySQL自己看着办!!
查看一下此时该表中的数据!
select * from java_student;
根据运行结果,我们可以看出,自增主键真的会给id分配一个唯一的且不为空的数据!!
MySQL给每个表维护了一个全局变量,每次分配一个id,就全局变量自增,下次分配的时候,接着上次的继续分配!
自己手动配置一下吧!!
insert into java_student values(100,'李四');
此时,当我们再次插入数据,并且让MySQL自己分配的时候:
insert into java_student values(null,'王五');
我们来查看一下表中的数据!
select * from java_student;
这次自增主键的数字变成了101 !!因此,自增主键只需要一个变量,记录序号的最大值即可!每次都在这个基础上+1操作!(跟insert插入到小于该变量的为止无关,只在乎插入某一次序号的最大值!)
外键 ( foreign key ) 是用于建立和加强两个表数据之间的链接的一列或多列。通过将保存表中主键值的一列或多列添加到另一个表中,可创建两个表之间的链接。这个列就成为第二个表的外键。
对于外键所涉及到的知识很复杂(在MySQL语法中),所以,我也不能确保各位老铁一定能够理解了,但是,笔者一定会尽自己的最大努力将该案列讲述完整!!但是,若还有其他不理解的,请移步其他博主博客(请不要喷笔者,学生一枚,勿喷)!!
定义两张表:student 表,class表;
在class表中:
create table class(classId int primary key auto_increment,className varchar(20));
//classId 班级编号
//className 班级名称
在student表中:将student中的classId与class中的classId建立某种联系!
create table student(studentId int primary key auto_increment,
name varchar(20),classId int,
foreign key (classId) references class(classId));
//因为上面的代码写在一行有点多,所以笔者分行来写的!当然,在MySQL中,也能这样写!!
//classId:班级Id (同学在那个班级)!
//对该代码foreign key (classId) references class(classId))进行解析!
//foreign key 外键
// (classId) 指定列
//references 关联
经过class 表与student表的建立,此时就要求我们,在student表中记录的classId,都得在class表的classId中存在!在这两个表中,student受到class表的约束,就把class叫做student的父表(parent),student就是class的子表(child)!!
在这种情况下student表与class表中:使用了外键,就得先对父表插入数据!MySQL拿着这个记录的classId 去class表查看一下,看看有没有,必须有才能完成后续的插入,如果没有,则插入失败!!不光是插入受到外键的影响,删除/修改也会受到外键的影响!!
父亲在约束孩子的时候,孩子未尝也不是在反向约束父亲!当子表已经关联父表某个数据的时候,对父表的数据进行该数据的修改/删除,都不可以!!(孩子已经依赖该数据!)
外键的使用情况!
对于外键的使用,笔者用一个电商类网站来介绍一下!
//商品表:
id,name,price…………
//订单表:
orderld,uesrld,goodsId,time…………
//要求:订单表中的goodsId 得在商品表(id)中存在(使用外键)
在外键不能解除的情况下,如果我们将商品表中的某商品下架处理,但是,订单表仍然可以查看,外键不能解除,那么,再在商品表中增添一列,表示是否下架,此时的下架并非是delete记录,而是update,把是否下架字段进行修改……(如:1表示上架,0表示下架)(逻辑删除,将数据标识为无效)!
子表中的数据(记录)需要在父表中存在,针对子表进行插入数据/修改数据,都需要去父表中查询一次,此时,如果父表中的数据很多,去父表查询一次,开销就很大,为了查找更快,可以给父表的对应列设置“索引”,这也就相当于不在遍历,可以加快速度!——》索引:主键(自带索引)/unique确保唯一!
为什么要使用外键?
保证数据的参照完整性。
不用也不会怎么样,如果一个健壮的系统,数据库中的数据一定有很好的参照完整性,如果不用外键,就要多写代码对数据的完整性进行额外的判断 。