总结三种MySQL外键约束方式

如果表A的主关键字是表B中的字段,则该字段称为表B的外键,表A称为主表,表B称为从表。外键是用来实现参照完整性的,不同的外键约束方式将可以使两张表紧密的结合起来,特别是修改或者删除的级联操作将使得日常的维护工作更加轻松。这里以MySQL为例,总结一下3种外键约束方式的区别和联系。

这里以用户表和用户组表为例,这是一个典型的多对一关系,多个用户对应于一个用户组。

  首先创建用户组表:

  创建用户组表

create table t_group (
  id int not null,
  name varchar(30),
  primary key (id)
  );

并插入两条记录:

  插入记录

insert into t_group values (1, 'Group1');
insert into t_group values (2, 'Group2');

下面创建用户表,分别以不同的约束方式创建外键引用关系:

  1、级联(cascade)方式

  级联方式

create table t_user (
  id int not null,
  name varchar(30),
  groupid int,
  primary key (id),
  foreign key (groupid) references t_group(id) on delete cascade on update cascade
  );

参照完整性测试

insert into t_user values (1, 'qianxin', 1); #可以插入
insert into t_user values (2, 'yiyu', 2); #可以插入
insert into t_user values (3, 'dai', 3); #错误,无法插入,用户组3不存在,与参照完整性约束不符

约束方式测试

insert into t_user values (1, 'qianxin', 1);
insert into t_user values (2, 'yiyu', 2);
insert into t_user values (3, 'dai', 2);
delete from t_group where id=2; #导致t_user中的2、3记录级联删除
update t_group set id=2 where id=1; #导致t_user中的1记录的groupid级联修改为2

2、置空(set null)方式

  置空方式

create table t_user (

  id int not null,

  name varchar(30),

  groupid int,

  primary key (id),

  foreign key (groupid) references t_group(id) on delete set null on update set null

  );
参照完整性测试insert into t_user values (1, 'qianxin', 1); #可以插入

  insert into t_user values (2, 'yiyu', 2); #可以插入

  insert into t_user values (3, 'dai', 3); #错误,无法插入,用户组3不存在,与参照完整性约束不符

约束方式测试

insert into t_user values (1, 'qianxin', 1);

  insert into t_user values (2, 'yiyu', 2);

  insert into t_user values (3, 'dai', 2);

  delete from t_group where id=2; #导致t_user中的2、3记录的groupid被设置为NULL

  update t_group set id=2 where id=1; #导致t_user中的1记录的groupid被设置为NULL

3、禁止(no action / restrict)方式

  禁止方式

create table t_user (

  id int not null,

  name varchar(30),

  groupid int,

  primary key (id),

  foreign key (groupid) references t_group(id) on delete no action on update no action

  );

参照完整性测试

insert into t_user values (1, 'qianxin', 1); #可以插入

  insert into t_user values (2, 'yiyu', 2); #可以插入

  insert into t_user values (3, 'dai', 3); #错误,无法插入,用户组3不存在,与参照完整性约束不符

约束方式测试

insert into t_user values (1, 'qianxin', 1);

  insert into t_user values (2, 'yiyu', 2);

  insert into t_user values (3, 'dai', 2);

  delete from t_group where id=2; #错误,从表中有相关引用,因此主表中无法删除

  update t_group set id=2 where id=1; #错误,从表中有相关引用,因此主表中无法修改

注:在MySQL中,restrict方式与no action方式作用相同。

mysql外键约束总结的更多相关文章

  1. mysql 外键约束备注

    梳理mysql外键约束的知识点. 1.mysql外键约束只对InnoDb引擎有效: 2.创建外键约束如下: DROP TABLE IF EXISTS t_demo_product; CREATE TA ...

  2. MySQL外键约束On Delete、On Update各取值的含义

    主键.外键和索引的区别?   主键 外键 索引 定义: 唯一标识一条记录,不能有重复的,不允许为空 表的外键是另一表的主键, 外键可以有重复的, 可以是空值 主索引(由关键字PRIMARY定义的索引) ...

  3. MySql 外键约束 之CASCADE、SET NULL、RESTRICT、NO ACTION分析和作用

    MySQL有两种常用的引擎类型:MyISAM和InnoDB.目前只有InnoDB引擎类型支持外键约束.InnoDB中外键约束定义的语法如下: ALTER TABLE tbl_name ADD [CON ...

  4. Mysql外键约束设置使用方法

    如果表A的主关键字是表B中的字段,则该字段称为表B的外键,表A称为主表,表B称为从表.外键是用来实现参照完整性的,不同的外键约束方式将可以使两张表紧密的结合起来,特别是修改或者删除的级联操作将使得日常 ...

  5. mysql 外键约束

    外键的定义语法:[CONSTRAINT symbol] FOREIGN KEY [id] (index_col_name, ...)    REFERENCES tbl_name (index_col ...

  6. MYSQL外键约束的参照操作

    如果表A的主关键字是表B中的字段,则该字段称为表B的外键,表A称为主表,表B称为从表.外键是用来实现参照完整性的,不同的外键约束方式将可以使两张表紧密的结合起来,特别是修改或者删除的级联操作将使得日常 ...

  7. 1、Mysql无法创建外键的原因 2、MySql 外键约束 之CASCADE、SET NULL、RESTRICT、NO ACTION分析和作用

    在Mysql中创建外键时,经常会遇到问题而失败,这是因为Mysql中还有很多细节需要我们去留意,我自己总结并查阅资料后列出了以下几种常见原因. 1.  两个字段的类型或者大小不严格匹配.例如,如果一个 ...

  8. MySQL外键约束_ON DELETE CASCADE/ON UPDATE CASCADE

    MySQL通过外键约束实现数据库的参照完整性,外键约束条件可在创建外键时指定,table的存储引擎只能是InnoDB,因为只有这种存储模式才支持外键. 外键约束条件有以下4种: (1)restrict ...

  9. mysql 外键约束示例

    -- 创建测试主表. ID 是主键.CREATE TABLE test_main (  id      INT,  value   VARCHAR(10),  PRIMARY KEY(id)); -- ...

随机推荐

  1. 前端之jQuery02

    文档操作 重点:创建标签,jQuery里面没有这个方法 内部(子标签) 添加到指定元素内部后面 $(A).append(B): // B作为A的最后一个儿子元素:(把B追加到A) $(A).appen ...

  2. C++将链表反转的实现

    有题目的需求是求将链表反转,例如1->2->3->4->5转变成5->4->3->2->1,经典的是可以有两种解决方法,递归方式和非递归方式,下面给出C ...

  3. Linux 自定义总线类型

    #include <linux/module.h> #include <linux/init.h> #include <linux/device.h> // 按照 ...

  4. ubuntu中配置samba方法

    1.在保证能上网的前提下,安装samba软件包,中途出现是否执行,一直点击回车键 #sudo apt-get install samba #sudo apt-get install smbclient ...

  5. FPGA中逻辑复制

    copy from http://www.cnblogs.com/linjie-swust/archive/2012/03/27/FPGA_verilog.html 在FPGA设计中经常使用到逻辑复制 ...

  6. 1074 Reversing Linked List

    题意: 每k个元素反转链表,不足k个就不反转.如原链表为1→2→3→4→5→6,k=3,则反转后的链表为3→2→1→6→5→4:若k=4,则反转后的链表为4→3→2→1→5→6. 思路: 这题会比较烦 ...

  7. 文件操作方法大全以及文件打开的其他一些模式sys.stdout.write()就是标准输出到你当前的屏幕 sys.stdout.flush()把内存立即显示到您当前的屏幕

    read()会让你读取的光标变成最后.tell()把你现在文件的句柄的指针打印出来.文件的开头指针位置是0f.read(5)只读取5个字符串个数如果你想把光标移回去,移动到首位f.seek(0)f.d ...

  8. 七 Kafka Streams VS Consumer API

    1 kafka Streams:   概念: 处理和分析储存在Kafka中的数据,并把处理结果写回Kafka或发送到外部系统的最终输出点,它建立在一些很重要的概念上,比如事件时间和消息时间的准确区分, ...

  9. oracle的sqlldr时插入新列和固定数据

    ctl文件加入固定值 region CONSTANT '31', 加入默认时间 RECORD_DATE "sysdate" 最好数据也设置RECORD_DATE的默认值为sysda ...

  10. Flask之测试与部署

    5.1 蓝图Blueprint 为什么学习蓝图? 我们学习Flask框架,是从写单个文件,执行hello world开始的.我们在这单个文件中可以定义路由.视图函数.定义模型等等.但这显然存在一个问题 ...