我对natural join
,theta join
和inner join
感到困惑,因为他们都倾向于为下面给出的模式提供相同的结果。
按定义:
自然连接形成其两个参数的笛卡尔积,对两个关系模式中出现的属性执行强制相等的选择。
theta join是自然连接操作的扩展,允许我们在单个操作中组合选择和笛卡尔积
内连接使用给定的连接条件计算两个关系的theta连接。
考虑架构:
mysql> select * from loan;
+---------+-------------+--------+
| loan_id | branch_name | amount |
+---------+-------------+--------+
| L11 | Round Hill | 900 |
| L14 | Downtown | 1500 |
| L15 | Perryridge | 1500 |
| L16 | Perryridge | 1300 |
| L17 | Downtown | 1000 |
| L23 | Redwood | 2000 |
| L93 | Mianus | 500 |
+---------+-------------+--------+
7 rows in set (0.00 sec)
mysql> select * from borrower;
+---------------+---------+
| customer_name | loan_id |
+---------------+---------+
| Adams | L16 |
| Curry | L93 |
| Hayes | L15 |
| Jackson | L14 |
| Jones | L17 |
| Smith | L11 |
| Smith | L23 |
| Williams | L17 |
| Adams | L19 |
| Adams | L15 |
| Jones | L15 |
| Williams | L23 |
+---------------+---------+
12 rows in set (0.00 sec)
Natual Join
mysql> select * from loan l, borrower b where l.loan_id=b.loan_id;
+---------+-------------+--------+---------------+---------+
| loan_id | branch_name | amount | customer_name | loan_id |
+---------+-------------+--------+---------------+---------+
| L16 | Perryridge | 1300 | Adams | L16 |
| L93 | Mianus | 500 | Curry | L93 |
| L15 | Perryridge | 1500 | Hayes | L15 |
| L14 | Downtown | 1500 | Jackson | L14 |
| L17 | Downtown | 1000 | Jones | L17 |
| L11 | Round Hill | 900 | Smith | L11 |
| L23 | Redwood | 2000 | Smith | L23 |
| L17 | Downtown | 1000 | Williams | L17 |
| L15 | Perryridge | 1500 | Adams | L15 |
| L15 | Perryridge | 1500 | Jones | L15 |
| L23 | Redwood | 2000 | Williams | L23 |
+---------+-------------+--------+---------------+---------+
11 rows in set (0.01 sec)
Theta Join
mysql> select * from loan l join borrower b on l.loan_id=b.loan_id;
+---------+-------------+--------+---------------+---------+
| loan_id | branch_name | amount | customer_name | loan_id |
+---------+-------------+--------+---------------+---------+
| L16 | Perryridge | 1300 | Adams | L16 |
| L93 | Mianus | 500 | Curry | L93 |
| L15 | Perryridge | 1500 | Hayes | L15 |
| L14 | Downtown | 1500 | Jackson | L14 |
| L17 | Downtown | 1000 | Jones | L17 |
| L11 | Round Hill | 900 | Smith | L11 |
| L23 | Redwood | 2000 | Smith | L23 |
| L17 | Downtown | 1000 | Williams | L17 |
| L15 | Perryridge | 1500 | Adams | L15 |
| L15 | Perryridge | 1500 | Jones | L15 |
| L23 | Redwood | 2000 | Williams | L23 |
+---------+-------------+--------+---------------+---------+
11 rows in set (0.00 sec)
内部加入
mysql> select * from loan l inner join borrower b on l.loan_id=b.loan_id;
+---------+-------------+--------+---------------+---------+
| loan_id | branch_name | amount | customer_name | loan_id |
+---------+-------------+--------+---------------+---------+
| L16 | Perryridge | 1300 | Adams | L16 |
| L93 | Mianus | 500 | Curry | L93 |
| L15 | Perryridge | 1500 | Hayes | L15 |
| L14 | Downtown | 1500 | Jackson | L14 |
| L17 | Downtown | 1000 | Jones | L17 |
| L11 | Round Hill | 900 | Smith | L11 |
| L23 | Redwood | 2000 | Smith | L23 |
| L17 | Downtown | 1000 | Williams | L17 |
| L15 | Perryridge | 1500 | Adams | L15 |
| L15 | Perryridge | 1500 | Jones | L15 |
| L23 | Redwood | 2000 | Williams | L23 |
+---------+-------------+--------+---------------+---------+
11 rows in set (0.01 sec)
所有查询都返回相同的结果。他们之间有什么区别?
答案 0 :(得分:2)
https://en.wikipedia.org/wiki/Relational_algebra
提供您尝试理解的不同联接的最佳解释。
自然连接是两组之间最基本的连接类型。比较两个元组中元组的主键和相应外键的相等性,以得出连接的元组集。
用户@amalamalpm指出:
theta join允许任意比较关系。
因为theta连接允许任意比较,所以可以将自然连接视为theta连接的子集。
内连接是theta连接的sql实现,因此无论何时使用自然连接都会使用。
注意:在mysql中,您可以执行以下操作以获得自然连接。这需要更少的角色,并且被懒惰的人(像我一样)所青睐。
select * from loan natural join borrower
这也将删除两个集合中存在的重复字段loan_id
(即仅在结果集中显示一次)。
您编写查询的三种方法都是尝试获得相同的结果集。
您正在进行自然加入>>这是theta join的一个子集>>这是sql用语中的内连接。
所以mysql给你相同的结果集。 我没有对它们运行explain extended
所以我不能保证这个,但是我猜想mysql也会执行相同的查询。
答案 1 :(得分:1)
在自然加入中,加入属性的名称和域必须相同。
在内连接中,只有连接属性的域需要相同
theta连接允许任意比较关系(例如 ≥)。
答案 2 :(得分:0)
在MySQL中,所有这三个查询都是相同的。
select * from loan l, borrower b where l.loan_id=b.loan_id;
select * from loan l join borrower b on l.loan_id=b.loan_id;
select * from loan l inner join borrower b on l.loan_id=b.loan_id;
在实践中,每个查询都是 equi-joins 。
“从理论上讲,理论与实践之间没有区别。在实践中,有”
应用诸如“自然”,“theta”和“内在”等理论标签并不会改变所有这三个陈述相同的事实。所有这三个陈述都是一样的。
第一个语句只是使用旧式逗号语法进行连接操作。第一个语句中的逗号等同于JOIN
关键字。
在MySQL INNER JOIN
中与JOIN
同义。也就是说,添加或删除关键字INNER
没有任何影响。
谓词是谓词是谓词。返回的行必须满足条件,条件是在ON
子句还是WHERE
子句中指定(在内连接的情况下)并不重要。