文章目录
新增外键修改外键 & 删除外键外键作用外键条件外键约束
外键:foreign key:外面的键,即键不在自己表中:如果有一个字段指向另外一张表的主键,那么该字段称之为外键在表关系为一对多的时候,外键必须加在多表身上
新增外键
外键可以在创建表的时候或者创建表之后新增:但是要考虑数据的问题,因为外键字段的数据必须在父表主键字段中有值一张表可以有多个外键外键是维持表与表之间的关联关系:涉及到的两张表称之为父表与子表 (1)子表:外键所在的表称之为子表 (2)父表:外键指向的表称之为父表如果是一对多或多对一的关系,那么外键必须加多表一方:能够通过外键匹配到父表中唯一的一条记录在创建表的时候新增外键:在所有字段之后,使用foreign key(外键字段) references 父表(主键字段)新增外键语法1:在创建子表的时候指定外键字段
constrant 外键名称 foreign key(外键字段) references 父表(主键字段);
创建两种表
-- 创建班级表
create table class(
id int primary key,
course varchar(20) not null comment '课程',
room varchar(20) not null comment '教室'
)charset utf8;
-- constraint:约束、限制的意思
create table student(
id int primary key,
number varchar(20) not null comment '学号',
name varchar(20) not null comment '姓名',
gender varchar(10) default '男' comment '性别',
age tinyint unsigned default 0 comment '年龄',
height tinyint unsigned comment '身高',
cid int comment '外键: 指向班级表class的主键id字段',
constraint fk_student_class foreign key(cid) references class(id)
)charset utf8;
新增外键的方法2:在创建表之后追加外键字段:修改表结构
aler table 表名称 [constraint 外键名称] add foreign key(外键字段) references 主表名称(主键字段);
修改外键 & 删除外键
外键不可以修改:只能先删除再追加删除外键语法
alter table 表名称 drop foreign key 外键名称;
-- 一张表中可以有多个外键,每个外键名称不能相同
删除外键不能通过查看表结构体现:应该通过表创建语句来体现
外键作用
外键默认的作用有两点:一个是对父表,一个是对子表(外键字段所在的表称之为子表:外键字段引用的表称之为主表) (1)对子表约束:子表数据进行写操作(新增数据与更新数据)的时候,如果对应的外键字段在父表找不到对应的记录匹配:那么操作会失败:约束子表写操作 (2)对父表约束:父表数据进行写操作(删除数据或更新数据:都必须涉及到主键字段本身)时,如果对应的主键在子表中已经被引用,那么操作不允许(默认情况下是不被允许的,但是还是可以有解决方案的)
外键条件
外键要存在:首先必须保证表的存储引擎是innodb(默认的存储引擎):如果不是innodb存储引擎,那么外键可以创建不成功,但是不会报错,所以没有约束效果
外键字段的数据类型/列类型必须与父表的主键字段的数据类型完全一致一张表中的外键名称不能重复:当然系统自动生成的外键名称是不会重复的,如果自己显示指定外键名称就必须小心:外键名称就是那个constriant后面的名称增加外键字段时如果数据化已经存在:必须保证数据能够正确引用到父表
外键约束
外键约束指的就是外键的作用上面说的外键作用是外键的默认作用:其实可以通过对外键的需求进行定制操作外键约束有三种模式:都是针对父表的约束
district:严格模式:默认模式:父表不能删除或者更新一个已经被子表引用的记录:当然主键字段被更新
cascade:级联模式:父表的操作,对应子表关联的记录被删除
set null:置空模式:父表操作之后,子表对应的记录中的外键字段被置空NULL
通常的一个合理的做法: (1) 删除父表记录的时候子表对应记录中的外键字段置空 (2) 更新父表主键字段的时候子表关联的记录中的外键字段级联更新
-- 父表记录删除,子表中引用父表此记录的记录中的外键字段被置空 -- 前提:外键字段允许为空
-- 父表记录的主键字段更新,子表中引用父表此记录的记录中的外键字段级联更新
foreign key(外键字段)
references 父表(主键字段)
on delete set null -- 删除父表主键字段时,子表引用向的相关记录中的外键字段置为NULL
on update cascade -- 更新父表主键字段时,子表引用的相关
在实际开发中推荐使用楼上的外键约束模式:删除置空(外键字段允许为空),更新级联:而楼下的模式是:删除级联,更新级联
-- 父表记录删除,子表中引用父表此记录的记录被删除
-- 父表记录的主键字段更新,子表中引用父表此记录的记录中的外键字段级联更新
foreign key(外键字段)
references 父表(主键字段)
on delete cascade -- 删除父表主键,子表外键引用的所有记录都被级联删除
on update cascade -- 更新父表主键,子表外键引用的所有记录都被级联更新
案例:
-- 创建班级表
create table class(
id int primary key,
course varchar(20) not null comment '课程',
room varchar(20) not null comment '教室'
)charset utf8;
insert into class values(1, 'C', 'A302'),
(2, 'C++', 'A304'), (3, 'Java', 'A304');
-- constraint:约束、限制的意思
create table student(
id int primary key,
number varchar(20) not null comment '学号',
name varchar(20) not null comment '姓名',
gender varchar(10) default '男' comment '性别',
age tinyint unsigned default 0 comment '年龄',
height tinyint unsigned comment '身高',
cid int comment '外键: 指向班级表class的主键id字段',
constraint fk_student_class foreign key(cid) references class(id)
-- 主表记录删除时,子表中关联的记录全部被删除
on delete cascade
-- 主表记录主键字段更新时,子表中关联的记录中的外键字段全部被同步更新
on update cascade
)charset utf8;
insert into student values(1, 'b1407003', 'ycom', default, 20, 170, 1),
(2, 'b1407004', 'kitty', '女', 18, 170, 2);
虽然外键很强大,能够进行各种约束处理:但是对于应用程序来讲,外键约束降低了应用程序对数据的可控性:通常在实际开发中,很少使用外键约束来处理