mysql表之间的联系怎么看_Mysql 表与表之间的关系

一、前言

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

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

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

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

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

拆分表解决以上问题.

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

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

一对多

多对多

一对一

foreign key(外键)语法:

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

二、表与表之间的关系

(一) 一对多

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

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

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

id,name,gender,dep_name

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

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

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

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

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

93e267caf4dbfc7871bc309ac522d0ef.png

创建两张表:

#被关联表:

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_外交部 | 国际形象大使部门 |

+-----+--------------+--------------------------+

2035cd0bec18c60e5251ad16d6461970.png

0a1ded4a503595337bb5e4f84c93a03d.png

级联更新与级联删除

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 应该建在 使用频率较高的一方。

aaa6efcfdfe72059df7f8869ff1d72ce.png

创建表:

#被关联表

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设置成唯一

6e01aca6d7206f5100099cf9744e1caf.png

- 多对多:

也必须站在两张表的位置去思考;

- 错误示范:

- 创建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

);

- 问题: 无法知道哪张表是被关联表

b798c3552ea59661834121a4f498fa05.png

正确示范:

- 利用第三张表,为两张表建立“多对多外键关系”。

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;

  • 1
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值