MySQL学习日志--表之间的关系

一、表之间的关系类型

1.1 一对一

定义:A表中的一行数据对应B表中的一行数据,且B表中的一行数据也对应着A表中的一行数据。

比如:人员表和驾照表,每一个人只有一个驾照,每个驾照也只对应一个人。

1.2 一对多

定义:A表中的一行数据可对应B表中的多行数据,但B表中的一行数据仅能对应A表中的一行数据。这是数据库中最常见的关系类型。

比如:学生表和班级表,每个班级里有很多学生,但是每个学生只有一个班级。

1.3 多对多

定义:A表中的一行数据可对应B表中的多行数据,反之亦然。标与表之间的关联需要通过中间表(关联表)实现。

比如:比如学生表和课程表,每个学生要上多门课程,每门课程也有很多学生要参加。

二、外键与关系体现

2.1 什么是外键

外键(Foreign Key)是关系型数据库中的一个核心概念,它是用于建立两个表之间的关联关系的,通常情况下,一张表的主键会作为另一张表的外键,例如,学生表包含学生id、姓名等字段,班级表包含班级id、班级名称等字段,在设计数据库时,我们可以通过在学生表中添加班级id作为外键,建立与班级表的关联关系。

2.2 外键的语法

2.2.1 一对一和一对多

在一对一和一对多时,我们可以在创建表时在语句最后声明外键,具体语法如下:

sql 复制代码
-- 其中,"外键名"是为这个关系命名,是自定义的,本表外键列名就是在本表中外键的名字,
-- 之后就是这个字段作为主键时的那张表名 + (主表时它的名字)
CONSTRAINT 外键名 FOREIGN KEY (本表外键列名) REFERENCES 主表名(主表主键列名)

2.2.2 多对多

多对多的表关系之间会存在重复的情况,比如学生表和课程表,一个学生有多门课程,我们该选那门作为外键关联呢?反之也是如此。

虽然这些是重复的,但是他们的关系组合在一起就是独特的一个字段了,所以这时我们就需要再建一个表,在这个表中存放学生id和课程id,使他们在第三张表中一一对应,这样也可以显现两张表之间的关系了。

1)我们可以在关系表中定义一个字段id作为这张表的主键,比如:

sql 复制代码
CREATE TABLE t_s_c(
    id INT PRIMARY KEY AUTO_INCREMENT,
    sid INT,
    cid INT,
    CONSTRAINT fk_student_id GOREIGN KEY (sid) REFERENCES t_student(id),
    CONSTRAINT fk_course_id FOREIGN KEY (cid) REFERENCES t_course(id)
);

2)但是这样写我们会发现,这张表中出现了第三个字段,也就是关系表的id,但是这是一张关系表,如果我们只想要他连接的两张表的id出现在这里,进行一一对应该怎么办呢?但是又不能没有主键,所以我们就有第二种写法,我们可以定义一个联合主键。

sql 复制代码
CREATE TABLE t_s_c(
    sid INT,
    cid INT,
    CONSTRAINT fk_student_id GOREIGN KEY (sid) REFERENCES t_student(id),
    CONSTRAINT fk_course_id FOREIGN KEY (cid) REFERENCES t_course(id),
    PRIMARY KEY(sid,cid) --联合主键
);

2.3 不同关系中外键的设置

不同的关系中,外键该如何去建,一般建在哪,需要初学者去思考一下。如果一对多时,外键建在"一"的一方,那么肯定会出现咱们上边说的重复的情况,所以具体的建议如下:

  • 一对一关系:外键可以存在于任意一方,具体视实际需求而定。
  • 一对多关系:外键设置在"多"的一方。
  • 多对多关系:外键不直接存储在实体表中,而是建在第三张表(关系表)中。

2.4 表的创建和删除

表的创建和删除,我们需要考虑到这个表的建立,里边的内容完不完整,会不会影响到其他表。

下面是创建和删除的建议:

  • 创建:建议先创建没有外键的表。
  • 删除:建议先删除有外键的表。

三、表连接方式详解

表连接就是将不同的表通过外键的方式连接在一起形成一张大表,然后通过查询展示出来,其本身并不会对表内数据产生影响。

3.1 内连接

内连接的特点:只显示满足连接条件的数据,不满足条件的不显示。比如学生表和班级表:

学生表:

|------------|------|----------|
| student_id | name | class_id |
| 1001 | 张三 | 201 |
| 1002 | 李四 | 202 |
| 1003 | 王五 | null |

班级表:

|----------|------------|
| class_id | class_name |
| 201 | 一班 |
| 202 | 二班 |
| 203 | 三班 |

我们在执行内连接时,会将这两张表连接,但是内连接只会显示有一一对应关系的数据,所以'王五'没有班级id,同样203班也没有学生和它对应,所以连接后只会显示:

|------------|------|----------|------------|
| student_id | name | class_id | class_name |
| 1001 | 张三 | 201 | 一班 |
| 1002 | 李四 | 202 | 二班 |

这就是内连接的特点。

3.1.1 隐式内连接

也就是隐藏了内连接的语法,语法如下:

sql 复制代码
SELECT *
FROM student s, class c,
WHERE s.class_id = c.class_id;

3.1.2 显式内连接

显式连接,语法如下:

sql 复制代码
SELECT *
FROM student s
INNER JOIN class c
ON s.class_id = c.class_id;

3.2 外连接

外连接和内连接不同,他是以其中的一个表为依据,该表中的所有数据都会显示,即使对应的外键为空,但是另一个表中如果没有和这个表对应的数据,还是不会显示。说白了就像是通过一个表去查找另一个表的数据,查到了就写出来,没查到就空着这种逻辑。

如果以学生表为依据的话,那么查询的结果如下:

|------------|------|----------|------------|
| student_id | name | class_id | class_name |
| 1001 | 张三 | 201 | 一班 |
| 1002 | 李四 | 202 | 二班 |
| 1003 | 王五 | null | null |

3.2.1 左外连接

以左表为主表,左表所有数据均显示,右表满足连接条件的显示,不满足的不显示,语法如下:

sql 复制代码
SELECT 字段...
FROM 表1
LEFT [OUTER] JOIN 表2
ON 连接条件

3.2.2 右外连接

以右表为主表,右表所有数据均显示,左表满足连接条件的显示,不满足的不显示,语法如下:

sql 复制代码
SELECT 字段...
FROM 表1
RIGHT [OUTER] JOIN 表2
ON 连接条件

3.3 自连接

自连接,就是两张参与连接的表其实是同一张表,其实可以理解为把这个表拷贝了一份,把它当作两张不同的表去看待,一般会应用在查找这张表中某个数据的一些信息,比如:

  • 查找同一产品在不同时间的价格变化
  • 比较同一学生在不同学期的成绩变化

同时在使用时,我们需要给from和join的表都起别名来区分,具体的使用根据情况使用内连接或外连接。

3.4 多表连接

上面我们说了,两张表的连接结果可以当作是一张大表来看待,既然是一张表,那么他就可以和其他表进行连接,其实和子查询有点相似,也就是将第三张表和连接的大表作为表1和表2,去根据情景不同,使用内连接和外连接,然后如此如此可以一直嵌套下去。

相关推荐
MoonBit月兔2 小时前
海外开发者实践分享:用 MoonBit 开发 SQLC 插件(其三)
java·开发语言·数据库·redis·rust·编程·moonbit
尘似鹤2 小时前
Uboot移植--修改lcd和网络驱动
linux·学习·uboot
d111111111d2 小时前
STM32平衡车工具-匿名助手+虚拟串口如何使用。
笔记·stm32·单片机·嵌入式硬件·学习
式5162 小时前
大模型学习基础(七)强化学习概念回顾
学习
电商API_180079052472 小时前
进阶篇:电商商品评论情感分析 + 关键词挖掘(Python NLP 实战)
大数据·开发语言·网络·数据库·人工智能
麦麦鸡腿堡2 小时前
MySQL_INSERT UPDATE DELETE语句
数据库·mysql
老李四2 小时前
深入理解MySQL事务:特性、原理与实践
数据库·mysql
洋生巅峰2 小时前
股票爬虫实战解析
爬虫·python·mysql
SelectDB技术团队2 小时前
慢 SQL 诊断准确率 99.99%,天翼云基于 Apache Doris MCP 的 AI 智能运维实践
大数据·数据库·人工智能·sql·apache