数据库的连接操作

今天复习并整理一下数据库的连接操作。

基础概念

书上分为以下几种:
等值连接查询、非等值连接查询、自然连接查询、自身连接查询、外连接查询、复合条件连接查询
等值与非等值连接查询
Select A.*, B.* from A,B where A.id = B.id
等值连接是指连接运算符为“=”,使用其他运算符(如:>,<,>=,!=)的是非等值连接。
自然连接
就是把等值连接中重复属性列去掉。
Select A.id,name from A,B where A.id = B.id
在两个表中都出现的字段名,要加上表名前缀。
自身连接
一个表与自己进行连接,需要给表取两个别名。
Select a1.name,a2.age from A a1,A a2 where a1.id = a2.num

左外连接列出左边关系中的所有元组,将与左表没有的对应项的右表的列设为NULL。
右外连接则列出右边关系中的所有元组。
复合条件连接查询
也就是有多个where连接条件。


  • 内连接(等值连接、非等值连接、自然连接)
  • 外连接(左连接、右连接、全连接)
    全连接:完整外部连接,返回左表和右表中的所有行。
  • 交叉连接
    交叉联接返回左表中的所有行,左表中的每一行与右表中的所有行组合。交叉联接也称作笛卡尔积。

知识扩展

1,left join 和 inner join
对于left join,不管on后面跟什么条件,左表的数据全部查出来,因此要想过滤需把条件放到where后面。也就是,它会先根据on把所有数据都查出来,再根据where条件过滤。对于inner join,满足on后面的条件表的数据才能查出,可以起到过滤作用。也可以把条件放到where后面。
2, on、where、having的区别
on、where、having这三个都可以加条件的子句中,on是最先执行,where次之,having最后。
3, Union和Union All的区别
UNION 内部的 SELECT 语句必须拥有相同的列。Union和Union All的区别之一在于对重复结果的处理。Union All有重复数据。Union没有。
Union,对两个结果集进行并集操作,不包括重复行,同时进行默认规则的排序;
Union All,对两个结果集进行并集操作,包括重复行,不进行排序;
从效率上说,UNION ALL 要比UNION快很多,所以,如果可以确认合并的两个结果集中不包含重复数据且不需要排序时的话,那么就使用UNION ALL。
4,几种多表连接 hash join、merge join、 semi join
[1] Hash join散列连接是CBO 做大数据集连接时的常用方式,优化器使用两个表中较小的表(通常是小一点的那个表或数据源)利用连接键(JOIN KEY)在内存中建立散列表,将列数据存储到hash列表中,然后扫描较大的表,同样对JOIN KEY进行HASH后探测散列表,找出与散列表匹配的行。需要注意的是:如果HASH表太大,无法一次构造在内存中,则分成若干个partition,写入磁盘的temporary segment,则会多一个写的代价,会降低效率。
这种方式适用于较小的表完全可以放于内存中的情况,这样总成本就是访问两个表的成本之和。但是在表很大的情况下并不能完全放入内存,这时优化器会将它分割成若干不同的分区,不能放入内存的部分就把该分区写入磁盘的临时段,此时要有较大的临时段从而尽量提高I/O 的性能。
[2] Merge Join 是先将关联表的关联列各自做排序,然后从各自的排序表中抽取数据,到另一个排序表中做匹配。
因为merge join需要做更多的排序,所以消耗的资源更多。 通常来讲,能够使用merge join的地方,hash join都可以发挥更好的性能,即散列连接的效果都比排序合并连接要好。然而如果行源已经被排过序,在执行排序合并连接时不需要再排序了,这时排序合并连接的性能会优于散列连接。
[3] semi join 主要用在分布式环境下。Hive是基于Hadoop的一个数据仓库工具,可以将结构化的数据文件映射为一张数据库表,并提供简单的sql查询功能,可以将sql语句转换为MapReduce任务进行运行。
semi join最主要的使用场景就是解决exist in。
Hive不支持where子句中的子查询,SQL常用的exist in子句在Hive中是不支持的。
SELECT a.key, a.value
FROM a
WHERE a.key in (SELECT b.key FROM B);
可以改写为:
SELECT a.key, a.value
FROM a LEFT OUTER JOIN b ON (a.key = b.key)
WHERE b.key <> NULL;
一个更高效的实现为:
SELECT a.key, a.value
FROM a LEFT SEMI JOIN b on (a.key = b.key);

参考:
多表连接的三种方式
join和semi join

猜你喜欢

转载自blog.csdn.net/u010707315/article/details/82664874