在步入主题之前我们先了解一下数据库的“实体”和“关系”。 在数据库中,我们经常听到“实体”和“关系”的概念,这分别来自于实体-关系模型(ER模型)的两个基本要素。为了帮助大家更好地理解它们,将详细地介绍“实体”和“关系”。
实体(Entity)
在数据库中,实体是由一组属性(Attributes)定义的可区分对象,代表现实世界之中存在或概念上存在、并可以被清楚定义和区分的东西。一个实体的每个属性都包含一个数据值。
举个例子,假如你正在建立一个关于学生信息的数据库,那么”学生”就是系统中的一个实体类型。“学生编号”,“姓名”,“地址”,“年龄”等就是此实体的属性。当你填充了具体的学生数据时, 每一个学生就是一个实体实例。
关系(Relationship)
在数据库中,关系描述了实体之间的交互方式。关系可能是一对一(1:1)、一对多(1:M)、多对一(M:1)以及多对多(M:N)等这样的互动模式。
让我们以简单的例子来理解这几种关系:
-
一对一(1:1):比如一个人只能拥有一个身份证,一个身份证也只能对应一个人。
-
一对多(1:M):一个母亲可以有多个孩子,但每个孩子只有一个母亲。
-
多对一(M:1):许多学生可能来自同一个城市,这是一个学生(多)对城市(一)的关系。
-
多对多(M:N):一个学生可以选修多门课程,同时一门课程也可以被多个学生选修。
在实际数据库设计中,每类型的关系都构筑数据之间的桥梁,承载着业务逻辑和需求,并为我们存取、处理和分析数据提供了便利。比如在学校系统中,“学生” 和 “课程” 就可能存在一个多对多的关系,在解决这样的复杂需求时,我们常常会引入第三个“关联表”。
理解实体和关系帮助我们在设计和操作数据库时保持清晰的思路。它们是创建有效、易于管理并能满足用户需求的数据库框架的基础。
此外,在将实体关系模型转换为具体的数据库模型时,实体通常被转换为数据库表, 实体的属性则转为表里的字段,而关系则通过主键(Primary Key)与外键(Foreign Key)的指定来实现。
例如,如果我们有一个 “学生” 实体和一个 “课程” 实体,它们之间存在多对多的关系,那么我们可以通过主键和外键的方式建立一个新的 “学生选课记录” 表。这个表会包含 “学生ID” 和 “课程ID” 这两个字段,并且这两个字段都分别是 “学生” 表和 “课程” 表的主键,但在 “学生选课记录” 表中成为了外键。
如图所示:




通过以上讲述,我们可以看出实体和关系在组织和操纵数据方面起到了重要作用。它们不仅使得数据更加方便地得以存储和操纵,另一方面也能够形象直观地描述出数据元素之间的联系,为数据的综合利用提供了可能。
理解实体和关系在数据库设计、和日常使用中都是重要的一环。所以,当我们再次遇到这些概念时,知道它们如何以及为何被使用将使我们受益匪浅。接下来,开启我们今天讲解的重点“表关联”。
此外,我们还将探讨如何优化这些关联,以便在保证查询质量的同时提高运行效率。
1. 数据库表关联的类型
当我们在使用数据库时,表间关联是必不可少的操作,它可以帮助我们从多个分散的数据库表中获取整合后的信息。SQL主要有三种形式的表连接:内连接、外连接和自连接。还有一种特殊的链接交叉连接。
1.1 内连接(INNER JOIN):
内连接是最常见的一种数据表查询方式,也是最容易理解的类型。正如其名字所示,它只返回那些在两个表中都有匹配的行。

SELECT
Table_Course.CourseID
, Table_Course_Student.CourseID
FROM dw.Table_Course
INNER JOIN dw.Table_Course_Student
ON
Table_Course.CourseID = Table_Course_Student.CourseID
;
1.2 外连接 (OUTER JOIN):
外连接被分为左连接(LEFT JOIN或LEFT OUTER JOIN )、右连接(RIGHT JOIN 或 RIGHT OUTER JOIN)和全连接(FULL JOIN 或 FULL OUTER JOIN)。 左连接返回了左表所有的记录以及右边表中匹配的记录;如果存在左表没有但右表有的记录,结果集中则以 NULL 呈现。右连接和左连接相反。全连接则包含了左表和右表的所有记录,两者中任一不匹配的地方都会以NULL 表现。

SELECT
ts.studentid
,tcs.id
,tcs.courseid
FROM table_student AS ts
LEFT JOIN table_course_student AS tcs
ON
ts.studentid = tcs.studentid


SELECT
ts.studentid
,tcs.id
,tcs.courseid
FROM table_student AS ts
RIGHT JOIN table_course_student AS tcs
ON
ts.studentid = tcs.studentid


SELECT
ts.studentid
,tcs.id
,tcs.courseid
FROM table_student AS ts
FULL JOIN table_course_student AS tcs
ON
ts.studentid = tcs.studentid
1.3 自连接(SELF JOIN):
自连接是指表与其自身进行的连接,该操作通常需要利用别名来区分同一个表的不同实例。
SELECT
ts.studentid
,tcs.studentid
FROM table_student AS ts
, table_student AS tcs
WHERE ts.studentid = tcs.studentid

1.4 交叉连接(CROSS JOIN)也称作笛卡尔积 慎用!!!

SELECT
ts.studentid
,tcs.id
,tcs.courseid
FROM table_student AS ts
CROSS JOIN table_course_student AS tcs
注意:
1、‘ON’后面的关联条件不仅可以使用‘=’等值连接,还可以使用‘>、>=、<=、<、!>、!<和<>’进行不等值连接。
2、‘ON’后面的条件和‘WHERE’后面的条件会导致查询结果不一致;
--条件在WHERE后面
SELECT
ts.studentid
,tcs.id
,tcs.courseid
FROM dw.table_student AS ts
RIGHT JOIN dw.table_course_student AS tcs
ON ts.studentid = tcs.studentid
WHERE ts.studentid =3
--条件在ON后面
SELECT
ts.studentid
,tcs.id
,tcs.courseid
FROM dw.table_student AS ts
RIGHT JOIN dw.table_course_student AS tcs
ON ts.studentid = tcs.studentid
AND ts.studentid =3


2. 数据库表关联优化策略
通过以下策略可以进一步提升数据库表关联的性能:
2.1 使用索引:
如果我们经常在某一列上进行查询,则对该列建立索引可以大幅度减少查询所需的时间。这与书籍的目录有些相似,查找特定章节时,通过目录就可以直接跳转到相关页面。
CREATE INDEX idx_studentid
ON table_student (studentid);
2.2 选择最合适的联结类型:
内连接通常会比外部连接快,因为外部连接需要返回更多的结果。
2.3 减少连接的表数量:
如果理论允许,尽量减少关联查询中涉及到的表数量,可以提高效率。
2.4 按需查询:
不要把所有的列都包括在 SELECT 语句中。只选择需要的列,可以大大提高查询效率。
SELECT
ts.studentid
,tcs.studentid
FROM dw.table_student AS ts
, dw.table_student AS tcs
WHERE ts.studentid = tcs.studentid
ORDER BY ts.studentid
这里,我们仅选择了’studentid’ 和 ‘studentid’ 两个字段进行查询。
2.5 避免使用 NOT IN 和 <> 操作符:
在执行查询时,尽可能避免使用 NOT IN 和 <> 操作符。这两个操作符会使 SQL 遍历每一行以找到非匹配行。如果可能,试图改写查询逻辑或使用 EXISTS 代替。
2.6 使用已验证的子查询或派生表:
子查询和派生表可以帮助数据库更有效地管理内存,并且在处理大型数据集时,它们可以显著增强查询性能。
SQL优化还是得看具体执行计划去定向优化。关于如何去优化表关联,是大表放在前面还是小表放在前面?是使用子查询更好还是使用表关联更好?是选择内连接还是外连接?笛卡尔积是否可用?等等相关问题我们改期在详细的解说。
以上是关于数据库表关联以及对应的优化策略的讨论。无论你正在使用哪种类型的数据库,上述优化方法都是通用的,可以大减轻数据库的压力,提升查询运行效率。记住,设计良好的数据库模型和合理的查询优化方案,将使你在处理庞大和复杂数据时游刃有余。
祝大家数据库使用愉快,我们下期再见!记得关注我们哟!
部分图片来源网络,侵权删!
原文始发于微信公众号(运维小九九):SQL技巧:表关联及优化
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/218565.html