【MySQL】外键的变种

限于喜欢 提交于 2019-11-28 15:20:19

原文: http://blog.gqylpy.com/gqy/250

目录

三种关系

多对一

多对多

一对一


因为有foreign key的约束,使得两张表形成了三种关系:

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

重点理解如何找出两张表之间的关系

现在有A、B两张表
分析步骤:

1. 先站在A表的角度去找
:是否A表的多条记录可以对应B表的一条记录,如果是,则证明A表的一个字段 foreign key B表的一个字段(通常是id).

2. 再站在B表的角度去找
:是否B表的多条记录可以对应A表的一条记录,如果是,则证明B表的一个字段 foreign key A表的一个字段(通常是id).

3. 总结:
多对一
如果是步骤1成立,则是A表多对一B表
如果是步骤2成立,则是B表多对一A表

多对多
如果步骤1和步骤2同时成立,则证明这两张表是一个双向的多对一,即多对多,需要定义一个这两张表的关系表来专门存放二者的关系.

一对一
如果1和2都不成立,而是A表的一条记录唯一对应B表的一条记录,反之亦然。这种情况很简单,就是在A表 foreign key B表的基础上,将A表的外键字段设置成unique即可



三种关系

多对一

或者说是一对多

举例:书和出版社
一个出版社可以出版多本书,请看图:
![在这里插入图片描述](http://blog.gqylpy.com/media/ai/2019-03/463fea85-f6a4-4305-aff5-587f53b643e2.png)

# 创建出版社表mysql> create table press(    -> id int primary key auto_increment,    -> name varchar(20)    -> );Query OK, 0 rows affected (0.07 sec) # 创建书籍表mysql> create table book(    -> id int primary key auto_increment,    -> name varchar(20),    -> press_id int not null,    -> constraint fk_book_press foreign key(press_id) references press(id)    -> on delete cascade    -> on update cascade    -> );Query OK, 0 rows affected (0.05 sec) # 先往被关联表中插入记录mysql> insert into press(name) values    -> ('北京工业地雷出版社'),    -> ('人民音乐不好听出版社'),    -> ('知识产权没有用出版社');Query OK, 3 rows affected (0.00 sec)Records: 3  Duplicates: 0  Warnings: 0 # 再往关联表中插入记录mysql> insert into book(name, press_id) values    -> ('九阳神功',1),    -> ('九阴真经',2),    -> ('九阴白骨爪',2),    -> ('独孤九剑',3),    -> ('降龙十巴掌',2),    -> ('葵花宝典',3);Query OK, 6 rows affected (0.04 sec)Records: 6  Duplicates: 0  Warnings: 0 # 查询结果mysql> select * from book;                                                                           +----+-----------------+----------+| id | name            | press_id |+----+-----------------+----------+|  1 | 九阳神功        |        1 ||  2 | 九阴真经        |        2 ||  3 | 九阴白骨爪      |        2 ||  4 | 独孤九剑        |        3 ||  5 | 降龙十巴掌      |        2 ||  6 | 葵花宝典        |        3 |+----+-----------------+----------+6 rows in set (0.00 sec) mysql> select * from press;+----+--------------------------------+| id | name                           |+----+--------------------------------+|  1 | 北京工业地雷出版社             ||  2 | 人民音乐不好听出版社           ||  3 | 知识产权没有用出版社           |+----+--------------------------------+3 rows in set (0.00 sec)

多对多

举例:作者和书籍的关系
一个作者可以写多本书,一本书也可以有多个作者,即多对多。请看图:
![在这里插入图片描述](http://blog.gqylpy.com/media/ai/2019-03/67921b80-a73c-4aed-89b3-dcbced259f18.png)

# 创建书籍表mysql> create table book(    -> id int primary key auto_increment,    -> name varchar(20)    -> );Query OK, 0 rows affected (0.06 sec) # 创建作者表mysql> create table author(    -> id int primary key auto_increment,    -> name varchar(20)    -> );Query OK, 0 rows affected (0.18 sec) # 这张表用于记录author表与book表的关系mysql> create table author2book(    ->     id int not null unique auto_increment,    ->     author_id int not null,    ->     book_id int not null,    ->     constraint fk_author foreign key(author_id) references author(id)    ->     on delete cascade    ->     on update cascade,    ->     constraint fk_book foreign key(book_id) references book(id)    ->     on delete cascade    ->     on update cascade,    ->     primary key(author_id,book_id)    -> );Query OK, 0 rows affected (0.09 sec)  # 插入记录mysql> insert into author(name) values('egon'), ('alex'), ('wusir'), ('yuanhao');Query OK, 4 rows affected (0.00 sec)Records: 4  Duplicates: 0  Warnings: 0 mysql> insert into book(name) values('Python全栈'), ('Linux高级运维'), ('爬虫技术'), ('Web前端');Query OK, 4 rows affected (0.01 sec)Records: 4  Duplicates: 0  Warnings: 0 # 插入作者与书籍的对应关系mysql> insert into author2book(author_id, book_id) values    -> (1, 1),    -> (1, 2),    -> (2, 1),    -> (3, 1),    -> (4, 4),    -> (4, 3);Query OK, 6 rows affected (0.04 sec)Records: 6  Duplicates: 0  Warnings: 0 mysql> select * from author2book;+----+-----------+---------+| id | author_id | book_id |+----+-----------+---------+|  1 |         1 |       1 ||  2 |         1 |       2 ||  3 |         2 |       1 ||  4 |         3 |       1 ||  5 |         4 |       4 ||  6 |         4 |       3 |+----+-----------+---------+6 rows in set (0.00 sec)

一对一

举例:用户和博客
一个用户只能注册一个博客,即一对一的关系,请看图:
![在这里插入图片描述](http://blog.gqylpy.com/media/ai/2019-03/939923a5-6aab-4aa4-b47b-1f9c71a5e598.png)

# 创建用户表mysql> create table user(    -> id int primary key auto_increment,    -> name varchar(20)    -> );Query OK, 0 rows affected (0.11 sec) # 创建博客表mysql> create table blog(    ->     id int primary key auto_increment,    ->     url varchar(100),    ->     user_id int unique,    ->     constraint fk_user foreign key(user_id) references user(id)    ->     on delete cascade    ->     on update cascade    -> );Query OK, 0 rows affected (0.08 sec) # 插入用户表中的记录mysql> insert into user(name) values('alex'), ('wusir'), ('egon'), ('xiaoma');Query OK, 4 rows affected (0.04 sec)Records: 4  Duplicates: 0  Warnings: 0 # 插入博客表的记录mysql> insert into blog(url, user_id) values    -> ('http:/blog.csdn.net/alex', 1),    -> ('http:/blog.csdn.net/wusir', 2),    -> ('http:/blog.csdn.net/egon', 3),    -> ('http:/blog.csdn.net/xiaoma', 4);Query OK, 4 rows affected (0.00 sec)Records: 4  Duplicates: 0  Warnings: 0 # 查找wusir的博客地址mysql> select url from blog where user_id=2;+---------------------------+| url                       |+---------------------------+| http:/blog.csdn.net/wusir |+---------------------------+1 row in set (0.00 sec)

 

 



 

原文: http://blog.gqylpy.com/gqy/250

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!