• 【数据库】内连接、外连接、交叉连接


    基本概念

    关系模型(表)

    关系模型由关系数据结构、关系操作集合和关系完整性约束三部分组成。

    关系模型的数据结构非常简单:一张扁平的二维表

    • 元组:二维表中的具有相同数据类型的某一行
    • 属性:二维表中的具有相同数据类型的某一列
    • 笛卡尔积(Cartesian product):又称直积,分别用集合A和集合B的一个元素作第一、第二元素构成有序对,所有这样的有序对的集合称为A和B的笛卡尔积,记作A×B。
      其符号化表示为:A×B = {<x, y> | x∈A∧y∈B}。
      易证:若|A| = m,|B| = n,则|AB| = m*n。(|A|表示集合A的模,即 集合A中元素的个数为m个)

      例如:
      A={a, b}, B={0, 1, 2},则
      A×B={(a, 0), (a, 1), (a, 2), (b, 0), (b, 1), (b, 2)}
      B×A={(0, a), (0, b), (1, a), (1, b), (2, a), (2, b)}


    • 表:是实实在在地保存数据的实体,写入的数据都保存在表中
    • 视图:是一个虚拟表,其内容由查询定义
      同真实的表一样,视图包含一系列带有名称的列和行数据;但是,视图并不在数据库中以存储的数据值集形式存在。
      行和列数据来自由定义视图的查询所引用的表,并且在引用视图时动态生成。

    • 候选码:若关系中的一个属性或属性组的值能够唯一地标识一个元组,且他的真子集不能唯一的标识一个元组,则称这个属性或属性组做候选码。
    • 主键:如果在一个关系中,有多个候选码可以选择,则选定其中的一个作为该关系的主键。
      它的值用于唯一地标识表中的某一条记录。主关键字是一种唯一关键字。

    • 码:是一个或多个属性的集合。
    • 超码:是一个或多个属性的集合,超码中的这些属性可以让我们在一个实体集中唯一地标识一个实体。

      注意:虽然超码可以唯一标识一个实体,但是可能大多数超码中含有多余的属性。所以我们需要候选码。

    • 候选码:是极小的超码集,也就是它的任意真子集都不是超码,而他本身是超码。
    • 主码:是被选中用来在一个关系中区分不同元组的候选码。


    我来举个例子吧:
    学生表(学号,身份证号,姓名,性别)
    超码:(学号,性别)→(姓名)。学号和性别能唯一标识姓名一点问题都没有,但是其实标识姓名,只用学号就能标识了,不需要性别。
    候选码:(学号)→(姓名),(身份证号)→(姓名)。学号或身份证号都能唯一标识姓名。
    主码:(学号)→(姓名)。这是人为选择的,其实身份证号也能做主码。

    连接

    所谓"连接",就是两张表根据关联字段(就是ON后面的关联条件),组合成一个数据集。

    • 内连接(inner join):(以左右表内匹配的记录为主)表示只包含匹配的记录。只返回两张表匹配的记录。
    • 外连接(outer join):表示还包含不匹配的记录
      • 左连接(left join):(以左表所有的记录为主)又称左外连接,返回匹配的记录,以及表A多余的记录
      • 右连接(right join):(以右表所有的记录为主)又称右外连接,返回匹配的记录,以及表B多余的记录
      • 全连接(full join):(以两个表所有的记录为主)又称全外连接,返回匹配的记录,以及表A和表B各自的多余记录
    • 交叉连接(cross join):即 做笛卡尔积运算。
      表A和表B不存在关联字段,这时表A(共有n条记录)与表B(共有m条记录)连接后,一对一组合配对,会产生一张包含n*m条记录的新表,返回新表。


    上图中,表A的记录是123,表B的记录是ABC,颜色表示匹配关系。返回结果中,如果另一张表没有匹配的记录,则用null填充。


    例子:
    学生表:

    • s_id:学生学号
    • s_name:学生名称
    • s_class:学生班级

    老师表:

    • t_id:老师id
    • t_class:老师管理的班级
    • t_name:老师名称

    内连接(INNER JOIN)

    /* 内连接 */
    SELECT * FROM student INNER JOIN teacher ON s_class=t_class
    
    /* 我比较喜欢这种 */
    SELECT * FROM student,teacher WHERE s_class=t_class

    外连接(OUTER JOIN)

    左外连接(LEFT JOIN)

    /* 左连接 */
    SELECT * FROM student LEFT JOIN teacher ON s_class=t_class

    右外连接(RIGHT JOIN)

    /* 右连接 */
    SELECT * FROM student RIGHT JOIN teacher ON s_class=t_class

    全外连接(FULL JOIN)

    注意:Oracle数据库支持full join,mysql是不支持full join的,但仍然可以同过左外连接+union+右外连接实现。

    /* 全连接(不适用于MYSQL) */
    SELECT * FROM student FULL JOIN teacher ON s_class=t_class
    
    /* 全连接 */
    SELECT * FROM student LEFT JOIN teacher ON s_class=t_class
    UNION
    SELECT * FROM student RIGHT JOIN teacher ON s_class=t_class

    交叉连接(笛卡尔积)(CROSS JOIN)

    /* 交叉连接 */
    SELECT * FROM student CROSS JOIN teacher 

  • 相关阅读:
    编写一个函数将一个十六进制数的字符串参数转换成整数返回?
    设置一段文字的大小为6px?
    写clone()方法时,通常都有一行代码,是什么?
    abstract class和interface有什么区别?
    JDBC中的Statement 和PreparedStatement的区别?
    什么是MVC模式?   
    Struts2的Action中获取request对象的几种方式?
    Struts2的功能扩展点有哪些?
    说说&和&&的区别?
    Struts2里面有什么隐式对象?
  • 原文地址:https://www.cnblogs.com/blknemo/p/12391172.html
Copyright © 2020-2023  润新知