业务需求:用户表r_user保存用户名等信息。现需要给每个用户设置工作基地,一个用户可以有多个工作基地,多个用户也可以有一个工作基地,即多对多关系。(外键,若有两个表A,B,C是A的主键,而B中也有C字段,则C就是表B的外键,外键约束主要用来维护两个表之间数据的一致性)

设计方案:

方案一:建立一张用户基地表,与r_user与用户基地表,保持一对多的关系,如图所示,r_user的主键id做为r_user_base的外键user_id。通过r_user中的id,在r_user_base表中load该用户的所有工作基地。

方案二:建立一张个基地表base_info保存目前存在的所有基地,再建一张user_base关系表。如图所示,关系表user_base有两个外键user_id与base_id

方案一的特点是,只需要键一张表就可以完成业务需求。缺点是不够模块化,如果在其它地方还要用到基地信息,则还要再建基地表

方案二的特点是,用一张关系表连接两张信息表。便于信息表的维护与重复利用。

基于业务需求与以后扩展及重用性考虑,采用方案二实现需求。

在MySQL 3.23.44版本后,InnoDB引擎类型的表支持了外键约束。

外键的使用条件:

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}]

 cascade方式 

在父表上update/delete记录时,同步update/delete掉子表的匹配记录 
   On delete cascade从mysql3.23.50开始可用; on update cascade从mysql4.0.8开始可用 。

set null方式 

在父表上update/delete记录时,将子表上匹配记录的列设为null

要注意子表的外键列不能为not null

On delete set null从mysql3.23.50开始可用; on update set null从mysql4.0.8开始可用 
No action方式

如果子表中有匹配的记录,则不允许对父表对应候选键进行update/delete操作 
   这个是ANSI SQL-92标准,从mysql4.0.8开始支持 
Restrict方式 

同no action, 都是立即检查外键约束

建立人员信息表:

 CREATE TABLE `r_user` (
`id` bigint(20) NOT NULL AUTO_INCREMENT,
`NAME` varchar(20) DEFAULT NULL,
`PASSWORD` varchar(50) DEFAULT NULL,
`STAFF_NUM` varchar(20) DEFAULT NULL,
`USER_NAME` varchar(20) DEFAULT NULL,
PRIMARY KEY (`id`),
) ENGINE=InnoDB AUTO_INCREMENT=54 DEFAULT CHARSET=utf8 

建立基地信息表

 CREATE TABLE `branch_info` (
`ID` bigint(20) NOT NULL AUTO_INCREMENT,
`BRANCH_CODE` varchar(255) DEFAULT NULL,
`BRANCH_DESC` varchar(255) DEFAULT NULL,
PRIMARY KEY (`ID`)
) ENGINE=InnoDB AUTO_INCREMENT=19 DEFAULT CHARSET=utf8 

关系表:

 CREATE TABLE `user_work_base` (
`id` bigint(20) NOT NULL AUTO_INCREMENT,
`version` int(11) NOT NULL,
`user_id` bigint(20) NOT NULL ,
`base_id` bigint(20) NOT NULL ,
PRIMARY KEY (`id`),
CONSTRAINT `user_work_base_ibfk_1` FOREIGN KEY (`user_id`) REFERENCES `r_user` (`id`) ON DELETE CASCADE ON UPDATE CASCADE,
CONSTRAINT `user_work_base_ibfk_2` FOREIGN KEY (`base_id`) REFERENCES `branch_info` (`ID`) ON DELETE CASCADE ON UPDATE CASCADE
) ENGINE=InnoDB AUTO_INCREMENT=37 DEFAULT CHARSET=utf8

删除人员r_user表中人员A,关系表user_base自动删除A的关系数据。

如果外键使用Restrict方式,只删除A,则报错。

Cannot delete or update a parent row: a foreign key constraint fails (`maircrew`,`user_work_base`, CONSTRAINT `FK41EB46D32AA89EA0`

FOREIGN KEY (`user_id`) REFERENCES `r_user` (`id`))

MySql多对多关系中外键的应用的更多相关文章

  1. Mysql多对多关系的查询

    1.创建user表 2.创建gateway表 3.创建user_gateway表 4.创建device表 5.创建gateway_device表 6.创建一个实体类 public class Devi ...

  2. 【mysql】如何通过navicat配置表与表的多对一关系,一对一关系?设计外键的效果

    背景: 现在要将接口自动化测试结果持久化,当前只是每次运行接口测试,将测试结果通过邮件发送给项目组成员.邮件内容如下: 表设计: 为了呈现这个结果:我设计了2张表run_result和run_deta ...

  3. MySQL基础9-主键约束、外键约束、等值连接查询、一对一和多对多关系

    1.主键约束和外键约束 外键约束 * 外键必须是另一表的主键的值(外键要引用主键!) * 外键可以重复 * 外键可以为空 * 一张表中可以有多个外键! 概念模型在数据库中成为表 数据库表中的多对一关系 ...

  4. mysql中外键的特点

    mysql中外键的特点简单描述: 1.要求在从表中设置外键关系: 2.从表的外键列的类型和主表的关联列的类型要求一致或兼容,名称无要求: 3.主表的关联列必须是一个key(一般是主键或唯一键): 4. ...

  5. mysql更新(五) 完整性约束 外键的变种 三种关系 数据的增删改

    11-数据的增删改   本节重点: 插入数据 INSERT 更新数据 UPDATE 删除数据 DELETE 再来回顾一下之前我们练过的一些操作,相信大家都对插入数据.更新数据.删除数据有了全面的认识. ...

  6. jango 模型管理数据model,数据库外键主键与一对一,一对多,多对多关系

    四.models.py 定义和管理模型: 4.1模型class的属性就映射与数据库的字段参数 继承models.Model class TestClass(models.Model): 4.2在数据库 ...

  7. 【个人笔记】《知了堂》MySQL三种关系:一对一,一对多,多对多。

    一对一:比如一个学生对应一个身份证号.学生档案: 一对多:一个班可以有很多学生,但是一个学生只能在一个班: 多对多:一个班可以有很多学生,学生也可以有很多课程: 一对多关系处理: 我们以学生和班级之间 ...

  8. python 外键用法 多对多关系 ORM操作 模板相关

    一.app/models中写类(设计表结构) 1.普通类 class  A(models.Model): id=modles.AutoField(primary_key=True) name=mode ...

  9. MySQL表关系--外键

    一.外键前戏 如果我们把所有的信息都记录在一张表中会带来的问题: 1.表的结构不清晰 2.浪费磁盘空间 3.表的扩展性极差 所以我们要把这种表拆成几张不同的表,分析表与表之间的关系. 确定表与表之间的 ...

随机推荐

  1. 【点分治】poj1741 Tree / poj2114 Boatherds / poj1987 Distance Statistics

    三道题都很类似.给出1741的代码 #include<cstdio> #include<algorithm> #include<cstring> using nam ...

  2. [CF911D]Inversion Counting

    题目大意: 给你一个数列,翻转其中一个区间,问每次翻转过后逆序对个数的奇偶性. 思路: 首先树状数组求出一开始的奇偶性,然后考虑每次翻转对答案的贡献. 对于整个区间,我们可以把翻转转化成若干次交换. ...

  3. Jquery中的ajax应用(第九章PPT)

    <%@ page language="java" import="java.util.*" pageEncoding="ISO-8859-1&q ...

  4. nginx 实现 ajax 跨域请求

    原文:http://www.nginx.cn/4314.html   AJAX从一个域请求另一个域会有跨域的问题.那么如何在nginx上实现ajax跨域请求呢?要在nginx上启用跨域请求,需要添加a ...

  5. RedisTemplate SerializationFailedException: Failed to deserialize payload 异常解决

    问题描述: 使用RedisTemplate(spring-data-redis )进行redis操作的封装 , 现有一个incr的key , 当调用incr后返回值一切正常, 当对此key进行get调 ...

  6. mORMot访问远程数据库

    mORMot访问远程数据库 mORMot中提供了TOleDBJetConnectionProperties类来处理Access的mdb数据库的访问,自带线程池.通过TSQLDBServerHttpAp ...

  7. LVM分区管理和扩展

    一.LVM简介 LVM是 Logical Volume Manager(逻辑卷管理)的简写.LVM将一个或多个硬盘的分区在逻辑上集合,相当于一个大硬盘来使用,当硬盘的空间不够使用的时候,可以继续将其它 ...

  8. ylbtech-LanguageSamples-ConditionalMethods(条件方法)

    ylbtech-Microsoft-CSharpSamples:ylbtech-LanguageSamples-ConditionalMethods(条件方法) 1.A,示例(Sample) 返回顶部 ...

  9. 深入理解Hadoop集群和网络【转】

    http://os.51cto.com/art/201211/364374.htm 本文将着重于讨论Hadoop集群的体系结构和方法,及它如何与网络和服务器基础设施的关系.最开始我们先学习一下Hado ...

  10. Python 操作mongodb 简单实例

    1.建立数据库用户 要读写 mongo数据库,默认没有用户名和密码也可以对数据库进行读写操作,但是从安全的角度,最好给要操作的数据库建立用户名和密码. 打开mongo数据库服务,打开mongo.exe ...