一、前言

研究表与表之间的关系前,先要知道将所有数据存放在一张表中的弊端:

1.结构不清晰 ---> 不致命

2.浪费空间 ---> 不致命

3.可扩展性极差 ---> 不可忽视的弊端

就i好比将所有的代码存放在一个文件中,强耦合到了一起,而我们需要做的就是 ----> 解耦合 ----> 拆分表

拆分表解决以上问题.

需要给两张表之间,建立一种强有力的关系, 使用 “外键”。

foreign key(外键): 用来建立两张表之间的关系

  • 一对多
  • 多对多
  • 一对一

foreign key(外键)语法:

foreign key(当前表中建立关系的外键字段) references 被关联表名(id)

二、表与表之间的关系

(一) 一对多

一对多(左边表的多条记录对应右边表的唯一一条记录)

注意:必须先建立被关联表,再建立关联表

例如:定义一张员工部门表

id,name,gender,dep_name

注意: 要确定两张表之间的关系,必须站在两个位置去思考:是否是单向多对一还是双向多对一,还是一一对应的关系。

  1. 站在员工表的位置:多个员工能否对应一个部门?(能)

    员工与部门:多对一(员工表单向 多对一 部门表)

  2. 站在部门表的位置:多个部门能否对应一个员工?(不能)

总结:凡是单向 多对一的表关系,称之为 一对多 的外键关系,如下图所示

创建两张表:

#被关联表:
dep:
create table dep(
id int primary key auto_increment,
dep_name varchar(16),
dep_desc varchar(255)); #关联表:
emp:
create table emp(
id int primary key auto_increment,
name varchar(6),
age int,
gender enum('male','female'),
dep_id int not null,
foreign key(dep_id) references dep(id)); #插入数据:必须先插入被关联表(dep)的数据,再插入关联表(emp)的数据。 #插入dep的数据:
insert into dep(dep_name,dep_desc) values(
'nb_外交部', '国际形象大使部门'),
('sb_教学部', '造程序员部门!!!!'),
('技术部', '技术有限部门'); #插入emp的数据:
insert into emp(name, age, gender, dep_id)
values('tank', 17, 'male', 1),
('jason', 70, 'male', 2),
('sean', 50, 'male', 2),
('egon', 88, 'male', 2),
('owen', 95, 'female', 3); # 报错
insert into emp(name, age, gender, dep_id) values(
'baohan', 18, 'others', 999); 更新数据:
update emp set dep_id=100 where id=2; #报错
update dep set id=100 where id=1; #报错 # 要先删除已关联的dep_id字段,才能修改dep表中的关联id字段。
delete from emp where id=1;
update dep set id=100 where id=1; mysql> select * from emp;
+----+-------+------+--------+--------+
| id | name | age | gender | dep_id |
+----+-------+------+--------+--------+
| 2 | jason | 70 | male | 2 |
| 3 | sean | 50 | male | 2 |
| 4 | egon | 88 | male | 2 |
| 5 | owen | 95 | female | 3 |
+----+-------+------+--------+--------+
mysql> select * from dep;
+-----+--------------+--------------------------+
| id | dep_name | dep_desc |
+-----+--------------+--------------------------+
| 2 | sb_教学部 | 造程序员部门!!!! |
| 3 | 技术部 | 技术有限部门 |
| 100 | nb_外交部 | 国际形象大使部门 |
+-----+--------------+--------------------------+ 删除:先删除关联表中的记录,再删除被关联表中的记录
#先删除emp表中的dep_id为2的记录
delete from emp where dep_id=2;
#再删除dep表中id为2的记录
delete from dep where id=2; mysql> select * from emp;
+----+------+------+--------+--------+
| id | name | age | gender | dep_id |
+----+------+------+--------+--------+
| 5 | owen | 95 | female | 3 |
+----+------+------+--------+--------+
mysql> select * from dep;
+-----+--------------+--------------------------+
| id | dep_name | dep_desc |
+-----+--------------+--------------------------+
| 3 | 技术部 | 技术有限部门 |
| 100 | nb_外交部 | 国际形象大使部门 |
+-----+--------------+--------------------------+



级联更新与级联删除

  • on update cascade 级联更新
  • on delete cascade 级联删除

意思是 当更新或删除主键表时,那么外键表也会跟随一起更新或删除

再以上述例子为例:

创建两张表:

#被关联表:
dep:
create table dep(
id int primary key auto_increment,
dep_name varchar(16),
dep_desc varchar(255)); #关联表:
emp:
create table emp(
id int primary key auto_increment,
name varchar(6),
age int,
gender enum('male', 'female'),
dep_id int not null,
foreign key(dep_id) references dep(id)
on update cascade
on delete cascade
); #插入数据:必须先插入被关联表(dep)的数据,再插入关联表(emp)的数据。 #插入dep的数据:
insert into dep(dep_name,dep_desc) values(
'nb_外交部', '国际形象大使部门'),
('sb_教学部', '造程序员部门!!!!'),
('技术部', '技术有限部门'); #插入emp的数据:
insert into emp(name, age, gender, dep_id)
values('tank', 17, 'male', 1),
('jason', 70, 'male', 2),
('sean', 50, 'male', 2),
('egon', 88, 'male', 2),
('owen', 95, 'female', 3); 更新数据或删除数据:
#更新记录:
update dep set id=200 where id=1; mysql> select * from dep;
+-----+--------------+--------------------------+
| id | dep_name | dep_desc |
+-----+--------------+--------------------------+
| 2 | sb_教学部 | 造程序员部门!!!! |
| 3 | 技术部 | 技术有限部门 |
| 200 | nb_外交部 | 国际形象大使部门 |
+-----+--------------+--------------------------+ #删除记录
delete from dep where id=200; mysql> select * from dep;
+----+--------------+------------------------+
| id | dep_name | dep_desc |
+----+--------------+------------------------+
| 2 | sb_教学部 | 造程序员部门!!!! |
| 3 | 技术部 | 技术有限部门 |
+----+--------------+------------------------+

(二) 一对一

一对一:两张之间的关系 一一对应,将一张数据量比较大的表,拆分成两张表。

例如:数据量比较大的用户表

  • 用户表:多个用户 能否 对应 一个用户详情信息? 不能
  • 用户详情表:多个用户详情信息 能否 对应 一个用户? 不能

两张表之间都没有多对一的关系,就是“一对一”的外键关系。

  • 总表:user_info

    id, name, age, gender, hobby, id_card

  • 分表:user:

    id , name, age, detail_id(外键)

  • 分表:detail:

    id, gender, hobby, id_card

注意:1、user与detail表建立了 一对一的外键 关系。

2、foreign key 应该建在 使用频率较高的一方。

创建表:
#被关联表
detail
create table detail(
id int primary key auto_increment,
gender enum('male', 'female'),
hobby varchar(32),
id_card char(18)
); #关联表
user
create table user(
id int primary key auto_increment,
name varchar(6),
age int,
detail_id int unique,
foreign key(detail_id) references detail(id)
on update cascade
on delete cascade
); #插入数据
insert into detail(gender, hobby,id_card) values
('male','play ball',9527),
('female','rap',909),
('female','吃鸡',101),
('female','被吃鸡',404),
('female','HSNM',500
); insert into user(name,age,detail_id) values
('tank', 17,3),
('egon', 77,5),
('jason', 87,1),
('sean', 97,2),
('owen', 107,4); # 报错,一对一,关系必须 一一对应
insert into user(name,age,detail_id) values ('baohan',19,3); mysql> select * from user;
+----+-------+------+-----------+
| id | name | age | detail_id |
+----+-------+------+-----------+
| 1 | tank | 17 | 3 |
| 2 | egon | 77 | 5 |
| 3 | jason | 87 | 1 |
| 4 | sean | 97 | 2 |
| 5 | owen | 107 | 4 |
+----+-------+------+-----------+ mysql> select * from detail;
+----+--------+-----------+---------+
| id | gender | hobby | id_card |
+----+--------+-----------+---------+
| 1 | male | play ball | 9527 |
| 2 | female | rap | 909 |
| 3 | female | 吃鸡 | 101 |
| 4 | female | 被吃鸡 | 404 |
| 5 | female | HSNM | 500 |
+----+--------+-----------+---------+

(三) 多对多

多对多:一个作者可以写多本书,一本书也可以有多个作者,双向的一对多,即 多对多的外键关系

关联方式:foreign key + 一张新的表

要把book_id和author_id设置成唯一

- 多对多:
也必须站在两张表的位置去思考; - 错误示范: - 创建book表
create table book(
id int primary key auto_increment,
title varchar(20),
price int,
book_content varchar(255),
author_id int,
foreign key(author_id) references author(id)
on update cascade
on delete cascade
); - 创建author表
create table author(
id int primary key auto_increment,
name varchar(16),
age int,
book_id int,
foreign key(book_id) references book(id)
on update cascade
on delete cascade
); - 问题: 无法知道哪张表是被关联表

正确示范:
- 利用第三张表,为两张表建立“多对多外键关系”。
book:
create table book(
id int primary key auto_increment,
title varchar(20),
price int,
book_content varchar(255)); author:
create table author(
id int primary key auto_increment,
name varchar(16),
age int); book2author:
create table book2author(
id int primary key auto_increment,
book_id int,
author_id int,
foreign key(book_id) references book(id)
on update cascade
on delete cascade,
foreign key(author_id) references author(id)
on update cascade
on delete cascade
); #插入数据
- book
insert into book(title, price, book_content) values
('金瓶mei', 199, '讲述朦胧时光的小故事'),
('python从入门到断气', 2000, '学习如何一夜秃头'),
('三体', 200, '跟着大佬进入宇宙奇幻世界'); - author
insert into author(name, age) values
('egon', 68),
('jason', 88); - book2author:
insert into book2author(book_id, author_id) values
(1, 1),
(1, 2),
(2, 2),
(3, 1); # 报错, 插入的数据,book_id, author_id必须存在
insert into book2author(book_id, author_id) values (4, 4); # 更新或删除
# 更新
- update book set price=6666 where id=1;
- update book set id=4 where id=1;
# 删除
- delete from book where id=4;

Mysql 表与表之间的关系的更多相关文章

  1. mysql 之各种 join 之间的关系

    一.了解一下 mysql 中所拥有的各种 join left join(左联接):返回包括左表中的所有记录和右表中联结字段相等的记录  right join(右联接):返回包括右表中的所有记录和左表中 ...

  2. mysql thread_cache 和 thread_pool 之间的关系

    线程池是Mysql5.6的一个核心功能,对 于服务器应用而言,无论是web应用服务还是DB服务,高并发请求始终是一个绕不开的话题.当有大量请求并发访问时,一定伴随着资源的不断创建和释放,导 致资源利用 ...

  3. Mysql之库表操作(胖胖老师)

    SQL概念:结构化查询语言(SQL = Structured Query Language),也是一种编程语言(数据库查询和程序设计语言),可以用于数据的存取及查询,更新,管理关系型数据库系统ps: ...

  4. mysql中相关,无关子查询,表与表之间的关系以及编码和乱码的解决

    ※MySQL中的字符编码(注意,utf8中没有'-',跟Java中不一样)SHOW VARIABLES; //查看系统变量//查询字符编码相关的系统变量SHOW VARIABLES WHERE var ...

  5. MySQL表与表之间的关系详解

    外键 说到表与表之间的关系就不得不说到一个关键词:外键 MySQ中的外键是什么,和表与表之间有什么关联? 外键(foreign key)又叫外连接, 在数据库中发挥着重要的作用 尤其是对于表和表之间的 ...

  6. MySQL数据库:SQL语句基础、库操作、表操作、数据类型、约束条件、表之间的关系

    数据库相关概念: 1. 数据库服务器:运行数据库管理软件的计算机 2. 数据库管理软件:MySQL.Oracle.db2.slqserver 3. 库:文件夹,用来组织文件/表 4. 表:文件(类似于 ...

  7. MySQL 表之间的关系

    表之间的关系 # 定义一张部门员工表 emp id name gander dep_name dep_desc 1 ming male 教学部 教书 2 lilei male 教学部 教书 3 ham ...

  8. mysql 中表与表之间的关系

    如何找出两张表的对应关系 分析步骤: 1.先找出左表的角度去找 ​ 是否左表的多条记录可以对应右表的一条记录,如果是,则证明左表的一个字段foreign key 右表一个字段 (通常是id) 2.再站 ...

  9. mysql中,表与表之间的关系

     """ 1.字段的修改.添加.删除 2.多表关系(外键) 3.单表详细操作:增删改,查(各种条件) """ 字段操作  create ta ...

随机推荐

  1. How To Move Or Rebuild A Lob Partition

    How To Move Or Rebuild A Lob Partition [ID 761388.1]             改动时间 29-JUN-2010     类型 HOWTO     状 ...

  2. 我钟爱的HTML5和CSS3在线工具【转】

    我真的喜欢上了HTML5, CSS3, JavaScript编程,但是有一些代码还是需要一些辅助工具来做才行,例如,CSS3的Gradient渐变如果手写代码的话真的不爽,还有像animation动画 ...

  3. swiper仿tab栏切换

    转载  https://developers.weixin.qq.com/community/develop/article/doc/000040a5dc4518005d2842fdf51c13 小程 ...

  4. springboot2.04与activiti 6.0集成

    本文就不对activiti做解释,下面直接看项目集成 以下顺序方面根据我的理解来,可以先从第二章看,再看第一张与第三章 增加activiti表的API,备注用. 目录 一.springboot2.X集 ...

  5. javascript 变量的提升

    下面是一个关于全局和局部作用域的问题 var a = 123; function f(){ alert(a); var a = 1; alert(a); } f(); 大家第一眼看到后都会认为第一次a ...

  6. 原生sql和 TP sql怎么关联?

    整合后

  7. 我去!JS的原型是咋回事?

    我去!JS的原型是咋回事? 最近写公司的项目,写着写着发现自己的原型的理解还是不够透彻,又去网上查了一番资料,顺便总结一下,在顺便给到的朋友能提供一点帮助.如有遗漏,欢迎交流. 原型是啥?为什么要用原 ...

  8. PythonWeb框架之Django

    Django 简介: Django是一个开放源代码的Web应用框架,由Python写成.采用了MTV的框架模式,即模型Model,模板Template和视图View.此框架设计模式借鉴了MVC框架的思 ...

  9. 2018-2-13-wpf-使用-Dispatcher.Invoke-冻结窗口

    title author date CreateTime categories wpf 使用 Dispatcher.Invoke 冻结窗口 lindexi 2018-2-13 17:23:3 +080 ...

  10. linux清理函数

    每个非试验性的模块也要求有一个清理函数, 它注销接口, 在模块被去除之前返回所有资 源给系统. 这个函数定义为: static void   exit cleanup_function(void) { ...