theta 连接、等值连接和自然连接之间的区别

Posted

技术标签:

【中文标题】theta 连接、等值连接和自然连接之间的区别【英文标题】:Difference between a theta join, equijoin and natural join 【发布时间】:2011-12-13 18:49:58 【问题描述】:

当涉及到 theta 连接、等值连接和自然连接时,我无法理解关系代数。有人可以帮助我更好地理解它吗?如果我在 theta 连接上使用 = 符号,它与仅使用自然连接完全相同吗?

【问题讨论】:

是赏金中的引文……他没有在那儿引用 Codd,他是从我的回答中引用他的评论出现在下面。 Theta-join 是 relation JOIN attribute operator attribute relation。人们经常说“theta-join”,但实际上他们的意思是a generalization of theta-joinrelation JOIN predicate relation。 (类似于 SQL INNER JOIN ON。) 【参考方案1】:

theta join 允许任意比较关系(例如 ≥)。

equijoin 是使用相等运算符的 theta 连接。

自然连接是在每个关系中具有相同名称的属性上的等值连接。

此外,自然连接会删除相等比较中涉及的重复列,因此每个比较列中只保留 1 个;在粗略的关系代数术语中: ⋈ = πR,S-as ○ ⋈aR=aS

【讨论】:

自然连接会移除同名列 全部,还是只有一个? Equijoin 也会删除相等列,如果它们在两个表中具有相同的名称。 @outis,“theta join”中的“theta”是什么意思? @Pacerier :历史上,theta 连接中的theta 指的是用作连接标准的任意条件。 (参见数据库系统:Garcia-Molina、Ullman、Widom 的全书,第 2 章,Theta Join)【参考方案2】:

虽然解释确切差异的答案很好,但我想展示如何将关系代数转换为 SQL,以及这 3 个概念的实际价值是什么。

您问题中的关键概念是联接的概念。要了解联接,您需要了解笛卡尔积(该示例基于 SQL,其中等价的称为交叉联接,正如 onedaywhen 指出的那样);

这在实践中不是很有用。考虑这个例子。

Product(PName, Price)
====================
Laptop,   1500
Car,      20000
Airplane, 3000000


Component(PName, CName, Cost)
=============================
Laptop, CPU,    500
Laptop, hdd,    300
Laptop, case,   700
Car,    wheels, 1000

笛卡尔积 Product x Component 将是 - 波纹管或sql fiddle。可以看到有 12 行 = 3 x 4。显然,像“笔记本电脑”和“***”这样的行没有意义,这就是为什么在实践中很少使用笛卡尔积的原因。

|    PNAME |   PRICE |  CNAME | COST |
--------------------------------------
|   Laptop |    1500 |    CPU |  500 |
|   Laptop |    1500 |    hdd |  300 |
|   Laptop |    1500 |   case |  700 |
|   Laptop |    1500 | wheels | 1000 |
|      Car |   20000 |    CPU |  500 |
|      Car |   20000 |    hdd |  300 |
|      Car |   20000 |   case |  700 |
|      Car |   20000 | wheels | 1000 |
| Airplane | 3000000 |    CPU |  500 |
| Airplane | 3000000 |    hdd |  300 |
| Airplane | 3000000 |   case |  700 |
| Airplane | 3000000 | wheels | 1000 |

JOIN 旨在为这些产品增加更多价值。我们真正想要的是将产品与其关联的组件“连接”起来,因为每个组件都属于一个产品。这样做的方法是使用连接:

Pname 上的产品 JOIN 组件

相关的 SQL 查询是这样的(你可以玩所有的例子here)

SELECT *
FROM Product
JOIN Component
  ON Product.Pname = Component.Pname

结果:

|  PNAME | PRICE |  CNAME | COST |
----------------------------------
| Laptop |  1500 |    CPU |  500 |
| Laptop |  1500 |    hdd |  300 |
| Laptop |  1500 |   case |  700 |
|    Car | 20000 | wheels | 1000 |

请注意,结果只有 4 行,因为 Laptop 有 3 个组件,Car 有 1 个,Airplane 没有。这更有用。

回到您的问题,您询问的所有联接都是我刚刚展示的 JOIN 的变体:

自然连接 = 对所有同名列进行连接(ON 子句);它从结果中删除重复的列,而不是所有其他连接;大多数 DBMS(由各种供应商创建的数据库系统,如 Microsoft 的 SQL Server、Oracle 的 mysql 等)甚至都不支持这一点,这只是一种不好的做法(或故意选择不实现它)。想象一下,一个开发人员来了,将 Product 中第二列的名称从 Price 更改为 Cost。然后所有自然连接都将在 PName 和 Cost 上完成,因为没有数字匹配,所以结果为 0 行。

Theta Join = 这是每个人都使用的一般连接,因为它允许您指定条件(SQL 中的 ON 子句)。您几乎可以在任何您喜欢的条件下加入,例如前 2 个字母相似或价格不同的产品。在实践中,这种情况很少发生 - 在 95% 的情况下,您将加入相等条件,这导致我们:

Equi Join = 实践中最常用的一种。上面的例子是一个 equi 连接。数据库针对这种类型的连接进行了优化!等值连接的对立面是非等值连接,即当您在“=”以外的条件下连接时。数据库没有为此优化!它们都是一般 theta 连接的子集。自然连接也是 theta 连接,但条件 (theta) 是隐式的。

信息来源:大学 + 认证的 SQL Server 开发人员 + 最近完成了斯坦福大学的 MOO“数据库简介”,所以我敢说我对关系代数有了新的认识。

【讨论】:

您使用术语“笛卡尔积”有点松散。关系运算符乘积产生一个关系(与所有关系运算符一样!)SQL 中的CROSS JOIN 运算产生一个表表达式(列的行)。集合运算笛卡尔积产生一组对。 当您说“数据库”时,实际上是指“DBMS”,这是处理“概念”时的关键区别。 onedaywhen - 感谢所有有用的 cmets!感觉就像代码审查:)。我修复了笛卡尔积和 DBMS 问题。我坚持我的观点,即自然连接仅具有学术兴趣,重要的 DBMS(如 SQL Server)不会故意实现这一点 - 显式添加条件会导致更好的代码理解和维护。相关问题:***.com/questions/4826613/natural-join-in-sql-server @HLGEM:人们可以对SELECT * FROM... 提出类似的论点(也许你会这样做)。但它存在于语言中,存在于每个 SQL 实现中,而且我经常使用它(我打赌你也会这样做!)提示并非所有代码都是生产代码。 “自然”连接列的真正问题不在于更改名称,而是添加新名称,这些名称不得在系统中所有可能连接的表之间发生冲突。采用非常常见的列,例如“名称”,“描述”,......使用“自然连接”将使它们连接起来,而它是无意义的,更多的是违反业务逻辑并导致错误。所以是的,“自然加入”是危险的。除了(主/外)键列之外,它会强制您使用不同的名称并丢失“名称间距”。【参考方案3】:

@outis 的回答很好:关于关系的简洁和正确。

但是,SQL 的情况稍微复杂一些。

考虑通常的suppliers and parts database,但在 SQL 中实现:

SELECT * FROM S NATURAL JOIN SP;

将返回带有列的结果集**

SNO, SNAME, STATUS, CITY, PNO, QTY

在两个表中具有相同名称的列上执行连接,SNO。请注意,结果集有六列,并且只包含一列SNO

现在考虑一个 theta eqijoin,其中连接的列名必须明确指定(加上范围变量 SSP 是必需的):

SELECT * FROM S JOIN SP ON S.SNO = SP.SNO;

结果集将有七列,其中两列是SNO。结果集的名称是 SQL 标准所称的“依赖于实现”,但可能如下所示:

SNO, SNAME, STATUS, CITY, SNO, PNO, QTY

或者这个

S.SNO, SNAME, STATUS, CITY, SP.SNO, PNO, QTY

换句话说,SQL 中的NATURAL JOIN 可以考虑从结果集中删除具有重复名称的列(可惜不会删除重复的行-您必须记住将SELECT 更改为SELECT DISTINCT 自己)。


** 我不太清楚SELECT * FROM table_expression; 的结果是什么。我知道这不是关系,因为除其他原因外,它可以包含具有重复名称的列或没有名称的列。我知道它不是一个集合,因为除其他原因外,列顺序很重要。它甚至不是 SQL 表或 SQL 表表达式。我称之为结果集。

【讨论】:

JOIN ... USING(...) 也是如此。 为什么说“我不太清楚SELECT * FROM table_expression;的结果是什么” @Pacerier:呃,因为我不知道它是什么!上次我查看时,SQL 标准避免定义它是什么。我知道它不是什么(不是关系,不是集合,不是表,不是表表达式)。因此,为了便于参考,我使用了我自己的术语“结果集”。请注意,在关系模型中,涉及两个关系的操作的结果是一个关系。不能为 SQL AFAIK 做出等效的语句。【参考方案4】:

Natural 是 Equi 的一个子集,它是 Theta 的一个子集。

如果我在 theta 连接上使用 = 符号,它是否与刚才一样 使用自然连接???

不一定,但它会是一个 Equi。自然意味着您在所有类似命名的列上进行匹配,Equi 仅意味着您仅使用“=”(而不是“小于”、喜欢等)

不过,这只是纯粹的学术界,您可以使用关系数据库多年,却从未听说过有人使用这些术语。

【讨论】:

我怀疑当您说“关系数据库”时,我怀疑您的意思是其他东西,例如“SQL”。 使用非 SQL 的关系数据库从事非学术界的工作?那么您指的是哪些产品? 在 Codd 的原始代数中,自然连接是连接的基本类型,而 equi-或 theta-“连接”是 NJ(例如叉积)后跟限制的简写。 “Natural 是 Equi 的一个子集,它是 Theta 的一个子集” 大概这意味着每个 NJ 也可以表示为 EJ 或 TJ。如果 σ 1=1 (A x B) 算作等值连接,我想这是正确的,在这种情况下,关系代数的每个运算都可以表示为该形式的等值连接。这里的模糊之处在于,RA 的基本运算符可能不止一组。 @EricFail:sqlvogel 只是引用了 kekekela 的答案,而不是 Codd 的任何内容。如果您想了解 Codd 关于连接(θ 或其他)的更多著作,您可以尝试“数据库管理的关系模型”,或者通过他的 bibliography 工作。 ... 您链接到的问题的答案与您正在寻找的内容接近,可能尽可能接近。它链接到Relational Completeness of Data Base Sublanguages。第 10 页描述了 θ、= 和自然连接之间的联系(虽然自然不是 Codd 公式中 = 的严格子集,而是 =-joins 的投影)。【参考方案5】:

Theta 加入: 当您使用任何运算符(例如,=、、>= 等)进行联接查询时,该联接查询属于 Theta 联接。等值联接: 当您仅使用相等运算符进行连接查询时,该连接查询属于 Equi 连接。

例子:

> SELECT * FROM Emp JOIN Dept ON Emp.DeptID = Dept.DeptID; > SELECT * FROM Emp INNER JOIN Dept USING (DeptID) 这将显示: _________________________________________________ |员工姓名 | Emp.DeptID |部门名称 |部门ID | | | | | |

注意:Equi 连接也是 theta 连接!自然连接: 一种 Equi Join 类型,通过比较两个表中的所有相同名称列隐式发生。

注意:这里,每对同名列的连接结果只有一列。

例子

 SELECT * FROM Emp NATURAL JOIN Dept
这将显示: ______________________________ |部门ID |员工姓名 |部门名称 | | | | |

【讨论】:

【参考方案6】:

两个表的笛卡尔积给出了所有可能的元组组合,就像数学中的例子一样,两个集合的叉积。因为很多时候有一些垃圾值在内存中也占据了不必要的空间,所以这里加入来救援,它只给出那些必需且有意义的属性值的组合。

内连接在表中给出了重复的字段两次,而这里的自然连接通过过滤重复的列并仅显示一次来解决问题。否则,两者的工作方式相同。自然连接更有效,因为它保留了内存。此外,在自然连接中删除了冗余。

两个表的

equi 连接使得它们只显示与其他表中的值匹配的那些元组。例如 : 让 new1 和 new2 成为两个表。如果 sql 查询 select * from new1 join new2 on new1.id = new.id (id 是两个表中的同一列)然后从 new2 表开始并加入与第二个表中的 id 匹配的连接。此外,非等号连接没有相等运算符,它们有 和之间的运算符。

theta join 由所有比较运算符组成,包括相等和其他 比较运算符。当它使用相等(=)运算符时,它被称为 equi join 。

【讨论】:

【参考方案7】:

自然连接:当两个关系中至少有一个共同属性时,自然连接是可能的。

Theta Join:当两个人在特定条件下行动时,Theta Join 是可能的。

Equi Join:当两个人在公平条件下行动时,Equi 是可能的。它是一种类型的 theta 连接。

【讨论】:

以上是关于theta 连接、等值连接和自然连接之间的区别的主要内容,如果未能解决你的问题,请参考以下文章

条件连接(θ连接),等值连接和自然连接之间的差异

SQL 等值连接(内连接)自然连接(Out join,Left join,Right join)的区别

mysql数据库——连接查询(内连接:自然连接,等值连接。外连接:左连接,右连接,全连接)

复合条件连接,内连接,左右连接,自然连接,等值连接

数据库Mysql--92非等值连接和自然连接

mysql的多表连接