一、前言

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

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. Tyvj-1338 QQ农场

    P1338 QQ农场 时间: 1000ms / 空间: 131072KiB / Java类名: Main 背景 Sandytea前段时间沉迷于QQ农场中……一天夜里,他梦见来到好友X的农场上…… 描述 ...

  2. oracle 用表连接替换EXISTS

    通常来说 , 采用表连接的方式比EXISTS更有效率 SELECT ENAME FROM EMP E WHERE EXISTS (SELECT ‘X’ FROM DEPT WHERE DEPT_NO ...

  3. ∆ (triangle)

    2.1 题目描述 给定一个无自环重边的无向图,求这个图的三元环1的个数以及补图2的三元环个数. 2.2 输入格式 第一行 2 个数 n, m ,分别表示图的点数.边数. 接下来 m 行,每行两个数 u ...

  4. [转]Jquery属性选择器(同时匹配多个条件,与或非)(附样例)

    1. 前言 为了处理除了两项不符合条件外的选择,需要用到jquery选择器的多个条件匹配来处理,然后整理了一下相关的与或非的条件及其组合. 作为笔记记录. 2. 代码 1 2 3 4 5 6 7 8 ...

  5. java声明异常(throws)

    在可能出现异常的方法上声明抛出可能出现异常的类型: 声明的时候尽可能声明具体的异常,方便更好的处理. 当前方法不知道如何处理这种异常,可将该异常交给上一级调用者来处理(非RuntimeExceptio ...

  6. 配置gitignore后使其生效命令

    改动过.gitignore文件之后,在repo的根目录下运行: git rm -r --cached . git add . 之后可以进行提交: git commit -m "fixed u ...

  7. java 声明多个泛型类型和通配符

    若一个类中多个字段需要不同的泛型声明,则在声明类的时候指定多个泛型类型即可: 格式: public interface IDAO<PK, T> { PK add(T t); void re ...

  8. P1002 Hello,World!

    题目描述 输出"Hello Wolrd!". 输入格式 无. 输出格式 输出一行"Hello World!". 样例输入 无. 样例输出 Hello World ...

  9. VisualStudio 扩展开发 获得输出窗口内容

    本文告诉大家如何拿到 VisualStudio 输出窗口的内容 在上一篇告诉大家如何开发添加菜单 点击的时候可以使用方法,如果需要拿到 VisualStudio 的输出窗口的内容,如想要开发一个插件, ...

  10. vue中 js获取图片尺寸 设置不同样式

    1.JS: 请求到后端数据后 判断图片尺寸 2.HTML代码 根据设置的类型,给图片添加不同的样式 3.CSS代码 添加不同尺寸的样式