SQL外键foreign key 表与表之间的三种关系

Posted 我的紫霞辣辣

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了SQL外键foreign key 表与表之间的三种关系相关的知识,希望对你有一定的参考价值。

表与表之间的三种关系

多对一关系表

注意事项:

  1. 一对多表关系,外键字段建在多的一方。
  2. 在创建表的时候,一定要先建被关联表。
  3. 在录入数据的时候,也必须先录入被关联表。
  4. 删除 一定要先删除主键表,才可以删除被关联表。
    在这里插入图片描述
# 创建表先创建被关联表(班级表)
create table class( 
id int primary key auto_increment,
name varchar(16),
room int
);

create table student(
id int primary key auto_increment,
name varchar(16),
age int not null,
gender enum("male","female","other")default"other",
class_id int,
foreign key(class_id) references class(id) 
on update cascade		# 级联更新(同步更新)
on delete cascade		# 级联删除(同步删除)
);

desc class;
+-------+-------------+------+-----+---------+----------------+
| Field | Type        | Null | Key | Default | Extra          |
+-------+-------------+------+-----+---------+----------------+
| id    | int(11)     | NO   | PRI | NULL    | auto_increment |
| name  | varchar(16) | YES  |     | NULL    |                |
| room  | int(11)     | YES  |     | NULL    |                |
+-------+-------------+------+-----+---------+----------------+

desc student;
+----------+-------------------------------+------+-----+---------+----------------+
| Field    | Type                          | Null | Key | Default | Extra          |
+----------+-------------------------------+------+-----+---------+----------------+
| id       | int(11)                       | NO   | PRI | NULL    | auto_increment |
| name     | varchar(16)                   | YES  |     | NULL    |                |
| age      | int(11)                       | NO   |     | NULL    |                |
| gender   | enum('male','female','other') | YES  |     | other   |                |
| class_id | int(11)                       | YES  | MUL | NULL    |                |
+----------+-------------------------------+------+-----+---------+----------------+

# 插入数据先创建被关联表的数据(class)
insert into class values(1,"java班级",304),
(2,"python班级",305),
(3,"web班级",306);

select * from class;
+----+--------------+------+
| id | name         | room |
+----+--------------+------+
|  1 | java班级     |  304 |
|  2 | python班级   |  305 |
|  3 | web班级      |  306 |
+----+--------------+------+

insert into student values(1,"nana",18,"female",1),
(2,"lala",19,"male",2),
(3,"dudu",16,"male",3),
(4,"haha",20,"male",1),
(5,"xixi",19,"male",2);

select * from student;
+----+------+-----+--------+----------+
| id | name | age | gender | class_id |
+----+------+-----+--------+----------+
|  1 | nana |  18 | female |        1 |
|  2 | lala |  19 | male   |        2 |
|  3 | dudu |  16 | male   |        3 |
|  4 | haha |  20 | male   |        1 |
|  5 | xixi |  19 | male   |        2 |
+----+------+-----+--------+----------+

多对多关系表

注意事项:

  1. 我们创建关联表的时候,如果双方都是被关联表,那么是无法创建成功的。
  2. 针对多对多关系字段的表,不能在两张原有的表中创建外键。
  3. 需要单独再创建一张媒介表专门用来存储两张表数据之间的关系。
    在这里插入图片描述
# 创建表先创建被关联表
create table book(
id int primary key auto_increment,
title varchar(16),
price int
);

create table author(
id int primary key auto_increment,
name varchar(16),
age int
);

create table book2_author(
id int primary key auto_increment,
book_id int not null,
author_id int not null,
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
);

desc book;
+-------+-------------+------+-----+---------+----------------+
| Field | Type        | Null | Key | Default | Extra          |
+-------+-------------+------+-----+---------+----------------+
| id    | int(11)     | NO   | PRI | NULL    | auto_increment |
| title | varchar(16) | YES  |     | NULL    |                |
| price | int(11)     | YES  |     | NULL    |                |
+-------+-------------+------+-----+---------+----------------+

desc author;
+-------+-------------+------+-----+---------+----------------+
| Field | Type        | Null | Key | Default | Extra          |
+-------+-------------+------+-----+---------+----------------+
| id    | int(11)     | NO   | PRI | NULL    | auto_increment |
| name  | varchar(16) | YES  |     | NULL    |                |
| age   | int(11)     | YES  |     | NULL    |                |
+-------+-------------+------+-----+---------+----------------+

desc book2_author;
+-----------+---------+------+-----+---------+----------------+
| Field     | Type    | Null | Key | Default | Extra          |
+-----------+---------+------+-----+---------+----------------+
| id        | int(11) | NO   | PRI | NULL    | auto_increment |
| book_id   | int(11) | NO   | MUL | NULL    |                |
| author_id | int(11) | NO   | MUL | NULL    |                |
+-----------+---------+------+-----+---------+----------------+

# 插入数据插入被关联数据
insert into book values(1,"python入门到放弃",1000),
(2,"葵花宝典",200),
(3,"撩妹大法",800),
(4,"独孤九贱",500);

select * from book;
+----+-----------------------+-------+
| id | title                 | price |
+----+-----------------------+-------+
|  1 | python入门到放弃      |  1000 |
|  2 | 葵花宝典              |   200 |
|  3 | 撩妹大法              |   800 |
|  4 | 独孤九贱              |   500 |
+----+-----------------------+-------+


insert into author values(1,"nana",18),
(2,"lala",16);

select * from author;
+----+------+------+
| id | name | age  |
+----+------+------+
|  1 | nana |   18 |
|  2 | lala |   16 |
+----+------+------+


insert into book2_author values(1,1,1),
(2,2,2),
(3,3,1),
(4,3,2),
(5,4,1),
(6,4,2);

select * from book2_author;
+----+---------+-----------+
| id | book_id | author_id |
+----+---------+-----------+
|  1 |       1 |         1 |
|  2 |       2 |         2 |
|  3 |       3 |         1 |
|  4 |       3 |         2 |
|  5 |       4 |         1 |
|  6 |       4 |         2 |
+----+---------+-----------+

一对一关系表

注意事项:

  1. 外键字段建在任意一方都可以,但是推荐设置在查询频率比较高的表中。
  2. 一对一关系表,只需要在多对一的情况下,将外键字段指定为unique即可。
    在这里插入图片描述
create table telephone(
id int primary key auto_increment,
iphone int,
addr varchar(16)
);

create table user(
id int primary key auto_increment,
name varchar(16),
age int,
telephone_id int unique,
foreign key(telephone_id) references telephone(id) 
);

desc telephone;
+--------+-------------+------+-----+---------+----------------+
| Field  | Type        | Null | Key | Default | Extra          |
+--------+-------------+------+-----+---------+----------------+
| id     | int(11)     | NO   | PRI | NULL    | auto_increment |
| iphone | int(11)     | YES  |     | NULL    |                |
| addr   | varchar(16) | YES  |     | NULL    |                |
+--------+-------------+------+-----+---------+----------------+

desc user;
+--------------+-------------+------+-----+---------+----------------+
| Field        | Type        | Null | Key | Default | Extra          |
+--------------+-------------+------+-----+---------+----------------+
| id           | int(11)     | NO   | PRI | NULL    | auto_increment |
| name         | varchar(16) | YES  |     | NULL    |                |
| age          | int(11)     | YES  |     | NULL    |                |
| telephone_id | int(11)     | YES  | UNI | NULL    |                |
+--------------+-------------+------+-----+---------+----------------+

insert into telephone values(1,666,"地球"),
(2,888,"M78星云");

select * from telephone;
+----+--------+-----------+
| id | iphone | addr      |
+----+--------+-----------+
|  1 |    666 | 地球      |
|  2 |    888 | M78星云   |
+----+--------+-----------+

insert into user values(1,"nana",18,1),
(2,"xixi",16,2);

select * from user;
+----+------+------+--------------+
| id | name | age  | telephone_id |
+----+------+------+--------------+
|  1 | nana |   18 |            1 |
|  2 | xixi |   16 |            2 |
+----+------+------+--------------+

建表遵循原则

以上是关于SQL外键foreign key 表与表之间的三种关系的主要内容,如果未能解决你的问题,请参考以下文章

mysql foreign key(外键) 说明与实例

三十九表与表之间的三种关系

6-[表操作]--foreign key表与表的关系

SQL数据库里面怎样设置表与表之间的关联

建表原则

表与表之间的关系