MYSQL基础系列之Mysql 外键说明

一、外键约束

      MySQL通过外键约束来保证表与表之间的数据的完整性和准确性。

二、外键的使用条件:

  1. 两个表必须是InnoDB表,MyISAM表暂时不支持外键(据说以后的版本有可能支持,但至少目前不支持);
  2. 外键列必须建立了索引,MySQL 4.1.2以后的版本在建立外键时会自动创建索引,但如果在较早的版本则需要显示建立; 
  3. 外键关系的两个表的列必须是数据类型相似,也就是可以相互转换类型的列,比如int和tinyint可以,而int和char则不可以;

三、外键的好处:可以使得两张表关联,保证数据的一致性和实现一些级联操作;

[CONSTRAINT symbol] FOREIGN KEY [id] (index_col_name, ...)

REFERENCES tbl_name (index_col_name, ...)

[ON DELETE {RESTRICT | CASCADE | SET NULL | NO ACTION | SET DEFAULT}]

[ON UPDATE {RESTRICT | CASCADE | SET NULL | NO ACTION | SET DEFAULT}]

该语法可以在 CREATE TABLE 和 ALTER TABLE 时使用,如果不指定CONSTRAINT symbol,MYSQL会自动生成一个名字。

ON DELETE、ON UPDATE表示事件触发限制,可设参数:

RESTRICT(限制外表中的外键改动)

CASCADE(跟随外键改动)在父表上update/delete记录时,同步update/delete掉子表的匹配记录 

SET NULL(设空值)父表中删除或更新对应的行,同时将子表中的外键列设为空。注意,这些在外键列没有被设为NOT NULL时才有效

SET DEFAULT(设默认值)父表有变更时,子表将外键列设置成一个默认的值 但Innodb不能识别

NO ACTION(无动作,默认的)

参照讲法就是这个网站:https://www.cnblogs.com/programmer-tlh/p/5782451.html,但我会把所有点尽量讲清楚。

————————————————————————愉快的分割线——————————————

1、创建数据库,设置字符集为utf-8

CREATE DATABASE `heibang` CHARACTER SET utf8 COLLATE utf8_general_ci;

2、首先我们先弄两个表出来,一个作为大佬表(dalao),一个作为菜鸟表(cainiao),这两者的关系就是一个大佬可以带着一群菜鸟。

CREATE TABLE dalao (
	`id` BIGINT (20) NOT NULL auto_increment primary key,
	`name` VARCHAR (50)
);

CREATE TABLE cainiao (
	`id` BIGINT (20) NOT NULL auto_increment primary key,
  `dalao_id` BIGINT (20) not null,
	`name` VARCHAR (50)
);

3、这时候,新增一个菜鸟

insert into cainiao(dalao_id,name) value(1,"菜鸟1号");

惊讶的发现这里多了个假大佬(大佬里面没有id为1的)带的菜鸟,不行,没有大佬带的菜鸟,容易做个混子,所以我们必须要让他有大佬带。不然菜鸟都不给做。

4-1RESTRICT、弄外键的时候到了。拒绝删除或者更新父表。指定RESTRICT(或者NO ACTION)和忽略ON DELETE或者ON UPDATE选项的效果是一样的。

alter table cainiao add constraint `cainiao_dalao_id` foreign key (`dalao_id`) references dalao(`id`) ON DELETE RESTRICT ON UPDATE RESTRICT;

4-1.1、添加一个菜鸟,理所当然的失败了。因为这时大佬里面没有id为2的。

insert into cainiao(dalao_id,name) value(2,"菜鸟2号");

这时MySQL会提示错误。

[Err] 1452 - Cannot add or update a child row: a foreign key constraint fails (`study`.`cainiao`, CONSTRAINT `cainiao_dalao_id` FOREIGN KEY (`dalao_id`) REFERENCES `dalao` (`id`))

大致意思是:菜鸟,想摸鱼呀!不找个真大佬,就想着摸鱼呀。

4-1.2、我们先添加一个大佬再来回来添加一个菜鸟吧

insert into dalao(id,name) value(2,"大佬2号");

4-1.3、这时我们来试着除掉大佬2号。

delete from dalao where id = 2;

这时MySQL会提示错误。

[Err] 1451 - Cannot delete or update a parent row: a foreign key constraint fails (`study`.`cainiao`, CONSTRAINT `cainiao_dalao_id` FOREIGN KEY (`dalao_id`) REFERENCES `dalao` (`id`))

大致意思是:不行呀,有限制的,大佬下面还有个菜鸟2号,可不能扔下不管。

4-1.4、那就先除掉大佬2号下面的菜鸟,解放大佬2号吧。

delete from cainiao where dalao_id = 2; delete from dalao where id = 2;

4-1.5、RESTRICT部分就到此就结束了。RESTRICT的作用就是用于限制,指的是如果字表引用父表的某个字段的值,那么不允许直接删除父表的该值。

注意:进行下面步骤是,如果提示外键重复,请先删除外键。

alter table cainiao drop foreign key cainiao_dalao_id;

4-2CASCADE、在父表上update/delete记录时,同步update/delete掉子表的匹配记录 

alter table cainiao add constraint `cainiao_dalao_id` foreign key (`dalao_id`) references dalao(`id`) ON DELETE CASCADE ON UPDATE CASCADE;

4-2.1、添加一个菜鸟,理所当然的失败了。因为这时大佬里面没有id为2的。

insert into cainiao(dalao_id,name) value(3,"菜鸟3号");

这时MySQL会提示错误。

[Err] 1452 - Cannot add or update a child row: a foreign key constraint fails (`study`.`cainiao`, CONSTRAINT `cainiao_dalao_id` FOREIGN KEY (`dalao_id`) REFERENCES `dalao` (`id`))

大致意思是:菜鸟,想摸鱼呀!不找个真大佬,就想着摸鱼呀。

4-2.2、我们先添加一个大佬再来回来添加一个菜鸟吧

insert into dalao(id,name) value(3,"大佬3号");

4-2.3、这时我们来试着除掉大佬3号。

delete from dalao where id = 3;

我们会发现执行成功了,大佬3号和下面的菜鸟都没了。

其余的就自己去尝试吧。我懒了。

扩展:no action和restrict的区别。在MySQL中都是一样的,原因如下:mysql会优先检查外键约束,然后再进行操作,而有些数据库则是no action会后检查,先操作,所以会引发差异。

说个有趣的事情,之所以了解外键,就只是为了,数据库表图,有个线能连起来

老规矩写的不清晰的地方,可以指出,我会不定时更新和修改。一起加油.

所有的伟大,都来自于一个勇敢的开始。

猜你喜欢

转载自blog.csdn.net/dubismile/article/details/88575846
今日推荐