表的连接方式
1、前言
最近在做项目,挺累的,但是还是少不了接着进行知识的总结,无论如何都挡不住我学习的心。接下来说正题,表的连接。多表
之间的连接在项目中还是挺常用的。我们做项目无论如何都不可能
只进行单表之间的CRUD,科普一下,我们平常总说的CRUD
全称是什么
- C ------ Create(增)
- R ------ Retrieve(查)
- U ------ Update(改)
- D ------ Delete(删)
表的连接方式有多种,了解它的原理
,将有助于我们在项目中灵活的应用连接以做出更高效的应用。
2、连接方式
表的连接分为:
- 内连接
- 外连接
- 左外连接
- 右外连接
- 全连接
- 自然连接
- 交叉连接
内连接
我们平常总使用
的大概也就是内连接了,那么内连接是什么呢,内连接大概是分为两个步骤的,第一个步骤就是先产生笛卡尔积,然后再消除笛卡尔积。关于笛卡尔积,大概是这么一种概念,类似于我们高中的时候接触的全排列,举个例子,有两队小朋友,第一队有5人,第二队有6人,一队的每人跟二队的每一个人进行握一次手,那么会产生30条轨迹,这就是内连接,会产生多余的数据,在实际项目中我们会消除掉笛卡尔积的,因为笛卡尔积中包含了部分我们不想要的记录,消除笛卡尔积就要指定消除笛卡尔积的条件。
官方的解释:
笛卡尔乘积是指在数学中,两个集合X和Y的笛卡尔积(Cartesian product),又称直积,表示为X×Y,第一个对象是X的成员而第二个对象是Y的所有可能有序对的其中一个成员
我这有两张表:密码存储表和密保存储表,表之间关系为一对多的关系。
两张表的数据
接下来看一下产生笛卡尔积是什么效果
select * from password_store ps, encrypted en;
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-otGbzpxm-1576340392445)(D:\typora文件\assets\TIM截图20191214234102.png)]
password_store中有5条数据,encrypted中有三条数据,所以两表产生的笛卡尔积就是3 x 5 = 15条记录,我们要消除笛卡尔积。即需要我们指定条件,在where后面指定,关于where和on的区别可以看另一篇我的博客一条sql是如何执行的。即只将两个表中满足条件记录结合到一起,不满足条件的记录过滤掉。
select * from password_store ps, encrypted en where ps.p_id = en.p_id;
两表相连如果不指定连接方式,默认就为内连接,也可以显示的指定
select * from password_store ps inner join encrypted en where ps.p_id = en.p_id;
但是如果指定了inner join
,就可以用on进行条件过滤,不显示指定,就只能使用where进行条件过滤。
外连接
左外连接:左外连接就是将左表中不满足指定条件的记录再加回到结果表中,然后其他的记录值为null。例如
select * from password_store ps left outer join encrypted en on ps.p_id = en.p_id;
注意:外连接必须指定条件,且在on中必须存在一个条件。在on后还可以再接where条件。
右外连接同理。
全连接
全连接(也叫全外连接)其实就是执行了两次外连接,一次左外连接,一次右外连接,然后将两次结果合并到一起。mysql中不支持全连接,但是可以用刚才的核心思想去模拟。
select * from password_store ps left outer join encrypted en on ps.p_id = en.p_id
union
select * from password_store ps right outer join encrypted en on ps.p_id = en.p_id;
另外在说一下union
和union all
的区别:
如果两表合并的结果中包含相同的记录,union会将这两条相等的记录过滤掉一条,而union all则不会过滤,两条都会显示。
自然连接
自然连接就是自动消除笛卡尔积,消除条件就是两张表中名称相同的字段。
select * from password_store natural join encrypted;
交叉连接
交叉连接又叫笛卡尔积连接,连接之后产生的都是笛卡尔积,需要我们手动进行消除笛卡尔积,类似于内连接。
交叉连接可以用on进行指定条件,也可以省略on,用where消除笛卡尔积。
select * from password_store ps cross join encrypted en on ps.p_id = en.p_id;
-- 或
select * from password_store ps cross join encrypted en where ps.p_id = en.p_id;
3、总结
(1)产生笛卡尔积需要手动清除笛卡尔积的连接:内连接、外连接、交叉连接。
(2)省略掉inner join
也是可以的 ,默认就为内连接。
(3)全连接就是进行两次外连接(左外连接、右外连接)。
(4)自然连接自动消除笛卡尔积,不用手动指定过滤条件。
(5)交叉连接可以使用on
指定过滤条件。
(6)外连接必需在on中指定至少一个条件。