如果公共关键字在一个关系中是主关键字,那么这个公共关键字被称为另一个关系的外键。由此可见,外键表示了两个关系之间的相关联系。以另一个关系的外键作主关键字的表被称为主表,具有此外键的表被称为主表的从表。
在实际操作中,将一个表的值放入第二个表来表示关联,所使用的值是第一个表的主键值(在必要时可包括复合主键值)。此时,第二个表中保存这些值的属性称为外键(foreign key)。
外键作用:保持数据一致性,完整性,主要目的是控制存储在外键表中的数据,约束。 使两张表形成关联,外键只能引用外表中的列的值或使用空值。
主表:grade
从表:student
-- 创建外键的方式一 : 创建子表同时创建外键
-- 年级表 (id\年级名称)
create table `grade`
(
`gradeid` int(10) not null auto_increment comment '年级id',
`gradename` varchar(50) not null comment '年级名称',
primary key (`gradeid`)
) engine = innodb
default charset = utf8;
-- 学生信息表 (学号,姓名,性别,年级,手机,地址,出生日期,邮箱,身份证号)
create table `student`
(
`studentno` int(4) not null comment '学号',
`studentname` varchar(20) not null default '匿名' comment '姓名',
`sex` tinyint(1) default '1' comment '性别',
`gradeid` int(10) default null comment '年级',
`phonenum` varchar(50) not null comment '手机',
`address` varchar(255) default null comment '地址',
`borndate` datetime default null comment '生日',
`email` varchar(50) default null comment '邮箱',
`idcard` varchar(18) default null comment '身份证号',
primary key (`studentno`),
key `fk_gradeid` (`gradeid`),
constraint `fk_gradeid` foreign key (`gradeid`) references `grade`
(`gradeid`)
) engine = innodb
default charset = utf8;
上面student创建时已经创建外键了,另外一种创建外键的方式是alter table,如下
alter table `student`
add constraint `fk_gradeid` foreign key (`gradeid`) references `grade`
(`gradeid`);
删除具有主外键关系的表时 , 要先删子表(从表:student),后删主表(grade),如果直接删除主表,看下具体会怎么样:
drop table `grade`
操作:删除 grade 表,发现报错
[HY000][3730] Cannot drop table 'grade' referenced by a foreign key constraint 'FK_gradeid' on table 'student'.
只有把从表的外键约束取消,才可以直接删除主表
-- 删除外键
alter table student drop foreign key fk_gradeid;
-- 发现执行完上面的,索引还在,所以还要删除索引
-- 注:这个索引是建立外键的时候默认生成的
alter table student drop index fk_gradeid;
如果只执行删除外键:alter table student drop foreign key fk_gradeid;
create table `student`
(
`studentno` int not null comment '学号',
`studentname` varchar(20) not null default '匿名' comment '姓名',
`sex` tinyint(1) default '1' comment '性别',
`gradeid` int default null comment '年级',
`phonenum` varchar(50) not null comment '手机',
`address` varchar(255) default null comment '地址',
`borndate` datetime default null comment '生日',
`email` varchar(50) default null comment '邮箱',
`idcard` varchar(18) default null comment '身份证号',
primary key (`studentno`),
key `fk_gradeid` (`gradeid`)
) engine = innodb
default charset = utf8mb3
两个都执行完成后, student和grade表之间就没有外键约束了,这时候可以删除表;
create table `student`
(
`studentno` int not null comment '学号',
`studentname` varchar(20) not null default '匿名' comment '姓名',
`sex` tinyint(1) default '1' comment '性别',
`gradeid` int default null comment '年级',
`phonenum` varchar(50) not null comment '手机',
`address` varchar(255) default null comment '地址',
`borndate` datetime default null comment '生日',
`email` varchar(50) default null comment '邮箱',
`idcard` varchar(18) default null comment '身份证号',
primary key (`studentno`)
) engine = innodb
default charset = utf8mb3