【MySQL】MySQL中的主键约束和外键约束,父子表的创建与删除

目录

总结

1.建立时先建父表再建子表

2.删除时先删子表再删父表

3.主键:非空且唯一

4.外键:关联其他表的主键或唯一值




总结

本文主要使用Navicat for MySQL工具 通过编程和代码测试 来分析SQL语言的常用约束条件:主键约束  和 外键约束。

在业务中每张表都需要有且仅有一个主键。

一张表中可以有多个外键,但是添加外键约束之后,字段添加外键约束的表作为子表,子表的外键引用来自父表的主键字段或唯一性约束的字段,被引用的表作为父表,父子表之间又有了需要注意的细节。

本文深入浅出,通过代码测试结合概念分析力求帮助读者彻底弄懂主键和外键。

1.建立时先建父表再建子表

先建立要引用的主表(外键来自何表)

再建立子表,按顺序执行,不然要报错

  • 🔲正确建表语句:
drop table if exists stu;
drop table if exists class;
create table stu
(
	sno int PRIMARY key,
	sname VARCHAR(10),
	major VARCHAR(10),
	cno int foreign key references class(cno)
);

create table class
(
	cno int primary,
	cname VARCHAR(5)
);

2.删除时先删子表再删父表

DROP TABLE IF EXISTS class;
DROP table if exists stu;

CREATE TABLE class
(
	cno int primary key,
	cname VARCHAR(10)
);

create table stu
(
	sno int primary key,
	sname VARCHAR(5),
	cno int,
	FOREIGN key(cno) REFERENCES class(cno)
); 

不然会报错:

正确删除方式:

3.主键:非空且唯一

主键一个表中只能有一个,可以有表级约束,也可以有列级约束。

主键就是非空约束(not null) 和 唯一性约束(unique)两者的结合

表级约束就是两个或者多个字段连起来 满足 上述要求!

主键的定义语句

sno int primary key;//列级约束,对学号这一字段(列,columu)进行约束,要求不为空且不能重复!
primary key(sno);//一个字段也可以这样使用表级约束,但是意义不大
primary key(name,id);//姓名和身份证号连起来,作为主键

尽管支持多个字段联合起来作为联合主键。

但是顺嘴提一句,并不推荐这样,实际业务中

第一范式就要求非主键不能对主键存在部分依赖。复合主键完美破解第一范式!

主键常用两种:

1,业务主键 业务主键是和业务挂钩的,数据重用效率低,业务发生变更太复杂,和业务有关,

2,自然主键 推荐使用自然主键,自然主键是和业务无关,自己玩自己的,业务变更不影响对数据的使用

其中自然主键非常常用且提到自然主键,不得不提到主键值自增,

如:在我们插入数据时,可以不管(自然主键),插入一条数据,主键值自动增长。

insert into class
(cname)
VALUES
('jd'),('jz'),('gk');

select * from class;


insert into stu
(sname,cno)
VALUES
('cwq',1),('ljb',2),('cyc',3);

select * from stu;

执行上述语句结果如下:

原因是我们在定义主键值的时候加入了这样一句话:

cno int primary key auto_increment;

auto_increment,主键值自增

4.外键:关联其他表的主键或唯一值

外键的约束条件

首先,外键是本表中的字段,本表是子表,通常外键引用父表的主键

但是当外键引用的是父表不为主键的字段

此时外键所约束的列,可以有一个或多个null同时出现 因为null不是值,不存在重复。

即可以不满足非空约束,但要求仍然满足unique的唯一性约束,不能有重复

外键:一言以蔽之:关联其他表的主键或唯一值

外键的声明语法:

foreign key(字段名) references 主表表名(列的字段名)

foreign key(字段名) references   主表表名(列的字段名)

不能向子表的外键所在列中插入父表对应列中不存在的元素!

[ SQL ]


插入到 stu (cno)值(7)中;

[ Err ]1452-无法添加或更新子行: 外键约束失败(‘ srs’)。‘ stu’,CONSTRAINT‘ stu _ ibfk _ 1‘ FOREIGN KEY (‘ cno’) REFERENCES‘ class’(‘ cno’))




[SQL]

insert into stu(cno) values(7);
[Err] 1452 - Cannot add or update a child row: a foreign key constraint fails (`srs`.`stu`, CONSTRAINT `stu_ibfk_1` FOREIGN KEY (`cno`) REFERENCES `class` (`cno`))

一个表中不限制外键的个数,但是子表中的列引用父表中的对应列,对应列 约束 应为主键约束或者唯一约束

解决方法:因为外键关联其他表的字段需要是主键,或者至少应满足唯一约束,因此加上唯一约束即可;

drop table if exists stu;
 drop table if exists class;

create table class
(
	cno int primary key auto_increment,
	cname VARCHAR(5) unique
);

create table stu
(
	sno int PRIMARY key auto_increment,
	sname VARCHAR(10),
	major VARCHAR(10),
	cno int ,
	cname VARCHAR(5),
	FOREIGN key (cno) references class(cno),
	foreign key (cname) references class(cname)
);

insert into class
(cname)
VALUES
('jd'),('jz'),('gk'),('gygc');

select * from class;


insert into stu
(sname,cno)
VALUES
('cwq',1),('ljb',2),('cyc',3);



insert into stu (cno) VALUES ('4');
select * from stu;

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

傻根根呀

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值