MySql多对多关系中外键的应用

业务需求:用户表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, 都是立即检查外键约束

建立人员信息表:

1 CREATE TABLE `r_user` (2   `id` bigint(20) NOT NULL AUTO_INCREMENT,3   `NAME` varchar(20) DEFAULT NULL,4   `PASSWORD` varchar(50) DEFAULT NULL,5   `STAFF_NUM` varchar(20) DEFAULT NULL,6    `USER_NAME` varchar(20) DEFAULT NULL,7   PRIMARY KEY (`id`),8   ) ENGINE=InnoDB AUTO_INCREMENT=54 DEFAULT CHARSET=utf8 

建立基地信息表

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

关系表:

1 CREATE TABLE `user_work_base` (2   `id` bigint(20) NOT NULL AUTO_INCREMENT,3   `version` int(11) NOT NULL,4   `user_id` bigint(20) NOT NULL ,5   `base_id` bigint(20) NOT NULL ,6   PRIMARY KEY (`id`),7   CONSTRAINT `user_work_base_ibfk_1` FOREIGN KEY (`user_id`) REFERENCES `r_user` (`id`) ON DELETE CASCADE ON UPDATE CASCADE,8   CONSTRAINT `user_work_base_ibfk_2` FOREIGN KEY (`base_id`) REFERENCES `branch_info` (`ID`) ON DELETE CASCADE ON UPDATE CASCADE9 ) 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`))

时间: 2024-12-12 15:50:43

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

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

四.models.py 定义和管理模型: 4.1模型class的属性就映射与数据库的字段参数 继承models.Model class TestClass(models.Model): 4.2在数据库生成数据表: #django默认在makemigrations会为表对象创建主键id,id = models.AutoField(primary_key=True) 你也可以自定义一个主键对象: 4.2.1: 生成迁移文件python manage.py makemigrations 4.2.2执行

数据库设计中一对一、多对一、多对多关系依据外键的实现条件及方法

作者:二歪求知iSk2y链接:https://www.jianshu.com/p/2b27c7ba0653来源:简书 下面以departments和staff_info表为例(为staff_info添加指向departments的外键) 一个表的字段作为外键的条件: 列值必须非空且唯一 测试例子如下: mysql> create table departments (dep_id int(4),dep_name varchar(11)); Query OK, 0 rows affected (0

数据库联合外键做主键(解决多对多关系)

多对多概念:一个学生可以学好几门课程,一门课程可以被好几个学生学习,站在某一个学生的角度就对应了多个课程,站在课程那里,就对应了多个学生,所以学生和课程就是一个简单的多对多关系. 在数据库中我们要解决这种多对多关系的应用,首先创建一个学生表,如 create table stu ( stu_id int primary key, sty_name varchar(20) ); 然后再创建一个课程表 create table book( book_id int primary key, book_

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

一.app/models中写类(设计表结构) 1.普通类 class  A(models.Model): id=modles.AutoField(primary_key=True) name=models.CharField(max_length=32,unique=True) 2.设置外键 class B(models.Model): id = models.AutoField(primary_key=True) title = models.CharField(max_length=32,

Mysql数据库多对多关系未建新表

原则上,多对多关系是要新建一个关系表的,当遇到没有新建表的情况下如何查询多对多的SQL呢? FIND_IN_SET(str,strlist) 官网:http://dev.mysql.com/doc/refman/5.7/en/string-functions.html Mysql数据库 此数据库为设计不合理的demo,仅用来示范多对多关系. 创建表结构 -- 新建user表 CREATE TABLE `user` ( `id` INT(11) NOT NULL COMMENT '人员id', `

MySQL的四种外键

转自:http://blog.csdn.net/cnjsnt_s/article/details/5548280 具体使用时需要参考:http://blog.csdn.net/codeforme/article/details/5539454 MySQL有两种常用的引擎类型:MyISAM和InnoDB.目前只有InnoDB引擎类型支持外键约束.InnoDB中外键约束定义的语法如下: [CONSTRAINT [symbol]] FOREIGN KEY [index_name] (index_col

Hibernate入门(三)—— 一对多、多对多关系

一.一对多关系 1.概念 ? 一对多关系是关系型数据库中两个表之间的一种关系.通常在数据库层级中,两表之间是有主外键关系的.在ORM中,如何通过对象描述表之间的关系,是ORM核心. 2.Hibernate的一对多关联映射[重点] 2.1表关系的分析 MySql语句 CREATE TABLE `t_category` ( `cid` int(11) NOT NULL AUTO_INCREMENT, `cname` varchar(255) DEFAULT NULL, PRIMARY KEY (`c

hibernate框架学习笔记9:多对多关系案例

员工与角色案例: 一个员工可以是多种角色(总监,经理),一种角色可以是多个员工(保洁) 这里发现无法使用外键表达关系,多对多总是创建第三张表来维护关系 这张表至少两列,都是外键,分别引用两张表的主键 员工(用户)实体类: package domain; //用户实体 import java.util.HashSet; import java.util.Set; public class User { private Long user_id; private String user_code;

ModelSerializer(重点) 基表 测试脚本 多表关系建外键 正反查 级联 插拔式连表 序列化反序列化整合 增删查 封装response

一.前戏要做好 配置:settings.py #注册drf INSTALLED_APPS = [ # ... 'api.apps.ApiConfig', 'rest_framework', ] ? #配置数据库 DATABASES = { 'default': { 'ENGINE': 'django.db.backends.mysql', 'NAME': 'dg_proj', 'USER': 'root', 'PASSWORD': '123', } } """ 在任何(根或者