Sự khác biệt giữa phép nối theta, phép nối tương đương và phép nối tự nhiên


92

Tôi đang gặp khó khăn khi hiểu đại số quan hệ khi nói đến các phép nối ta, phép nối tương đương và phép nối tự nhiên. Ai đó có thể vui lòng giúp tôi hiểu rõ hơn về nó? Nếu tôi sử dụng dấu = trên một phép nối theta thì nó có giống hoàn toàn với việc chỉ sử dụng một phép nối tự nhiên không?


là câu trích dẫn được đề cập từ tiền thưởng ... anh ấy không trích dẫn Codd ở đó, anh ấy đang trích dẫn từ câu trả lời của tôi mà bình luận của anh ấy xuất hiện bên dưới.
heisenberg

Câu trả lời:


138

Một phép nối theta cho phép các mối quan hệ so sánh tùy ý (chẳng hạn như ≥).

Một liên kết tương đương là một phép nối theta sử dụng toán tử bình đẳng.

Phép nối tự nhiên là phép nối tương đương trên các thuộc tính có cùng tên trong mỗi mối quan hệ.

Ngoài ra, phép nối tự nhiên loại bỏ các cột trùng lặp liên quan đến phép so sánh bình đẳng để chỉ còn lại 1 trong mỗi cột được so sánh; trong thuật ngữ đại số quan hệ thô: ⋈ = πR,S-as ○ ⋈aR=aS


13
phép nối tự nhiên sẽ xóa các cột có cùng tên
Bogdan Gavril MSFT

2
Tất cả chúng, hay tất cả trừ một?
Christopher Shroba

Equijoin cũng sẽ xóa cột bình đẳng nếu chúng có cùng tên trong cả hai bảng.
Vishal R

1
@outis, "theta" trong "theta join" nghĩa là gì?
Pacerier

2
@Pacerier: Về mặt lịch sử, phép nối thetatrong theta đề cập đến một điều kiện tùy ý được sử dụng làm tiêu chí cho phép nối. (xem Hệ thống cơ sở dữ liệu: Toàn bộ Sách của Garcia-Molina, Ullman, Widom, chương 2, Theta Tham gia)
Ram Rajamony

55

Mặc dù các câu trả lời giải thích sự khác biệt chính xác là tốt, nhưng tôi muốn chỉ ra cách đại số quan hệ được chuyển đổi sang SQL và giá trị thực của 3 khái niệm là gì.

Khái niệm chính trong câu hỏi của bạn là ý tưởng về sự tham gia. Để hiểu một phép nối, bạn cần hiểu một Sản phẩm Descartes (ví dụ dựa trên SQL trong đó phép tương đương được gọi là phép nối chéo như onedaywhen đã chỉ ra);

Điều này không hữu ích trong thực tế. Hãy xem xét ví dụ này.

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

Sản phẩm Descartes Sản phẩm x Thành phần sẽ là - dưới đây hoặc sql fiddle . Bạn có thể thấy có 12 hàng = 3 x 4. Rõ ràng, các hàng như "Máy tính xách tay" với "bánh xe" không có ý nghĩa gì, đây là lý do tại sao trong thực tế, sản phẩm Descartes hiếm khi được sử dụng.

|    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 |

Tham gia ở đây để tăng thêm giá trị cho các sản phẩm này. Những gì chúng tôi thực sự muốn là "kết hợp" sản phẩm với các thành phần liên quan của nó, bởi vì mỗi thành phần thuộc về một sản phẩm. Cách để làm điều này là với một tham gia:

Thành phần THAM GIA SẢN PHẨM TRÊN Pname

Truy vấn SQL được liên kết sẽ giống như thế này (bạn có thể chơi với tất cả các ví dụ ở đây )

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

và kết quả:

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

Lưu ý rằng kết quả chỉ có 4 hàng, vì Máy tính xách tay có 3 thành phần, Ô tô có 1 và Máy bay không có. Điều này hữu ích hơn nhiều.

Quay trở lại câu hỏi của bạn, tất cả các phép nối mà bạn hỏi đều là các biến thể của THAM GIA mà tôi vừa hiển thị:

Natural Join = phép nối (mệnh đề ON) được tạo trên tất cả các cột có cùng tên; nó loại bỏ các cột trùng lặp khỏi kết quả, trái ngược với tất cả các phép nối khác; hầu hết các DBMS (hệ thống cơ sở dữ liệu được tạo bởi các nhà cung cấp khác nhau như SQL Server của Microsoft, MySQL của Oracle, v.v.) thậm chí không quan tâm đến việc hỗ trợ điều này, nó chỉ là một thực tiễn xấu (hoặc cố tình chọn không triển khai nó). Hãy tưởng tượng rằng một nhà phát triển đến và thay đổi tên của cột thứ hai trong Sản phẩm từ Giá thành Chi phí. Sau đó, tất cả các phép nối tự nhiên sẽ được thực hiện trên PName VÀ trên Chi phí, dẫn đến 0 hàng vì không có số nào khớp.

Theta Join = đây là phép nối chung mà mọi người sử dụng vì nó cho phép bạn chỉ định điều kiện (mệnh đề ON trong SQL). Bạn có thể tham gia với bất kỳ điều kiện nào bạn thích, chẳng hạn như trên Sản phẩm có 2 chữ cái đầu tiên giống nhau hoặc có giá khác. Trong thực tế, điều này hiếm khi xảy ra - trong 95% trường hợp, bạn sẽ tham gia với điều kiện bình đẳng, dẫn đến việc:

Trang bị Tham gia = cái phổ biến nhất được sử dụng trong thực tế. Ví dụ trên là một phép nối trang bị. Cơ sở dữ liệu được tối ưu hóa cho loại liên kết này! Kết hợp của phép nối trang bị là phép nối không trang bị, tức là khi bạn tham gia với một điều kiện khác với "=". Cơ sở dữ liệu không được tối ưu hóa cho việc này! Cả hai đều là tập hợp con của tham gia theta chung. Phép nối tự nhiên cũng là phép nối theta nhưng điều kiện (theta) là ngầm định.

Nguồn thông tin: trường đại học + nhà phát triển SQL Server được chứng nhận + gần đây đã hoàn thành MOO "Giới thiệu về cơ sở dữ liệu" từ Stanford, vì vậy tôi dám khẳng định rằng tôi đã nghĩ đến đại số quan hệ.


1
Bạn sử dụng thuật ngữ 'sản phẩm Descartes' hơi lỏng lẻo. Sản phẩm toán tử quan hệ dẫn đến một quan hệ (chung với tất cả các toán tử quan hệ!) Một CROSS JOINphép toán trong SQL dẫn đến một biểu thức bảng (các hàng cột). Phép toán tập hợp Tích Đề-các dẫn đến một tập hợp các cặp.
onedaywhen ngày

1
Khi bạn nói "Cơ sở dữ liệu", bạn thực sự có nghĩa là "DBMS", một sự khác biệt quan trọng khi giải quyết các 'khái niệm'.
onedaywhen ngày

2
onedaywhen - cảm ơn bạn vì tất cả các ý kiến ​​hữu ích! cảm thấy giống như một đánh giá mã :). Tôi đã khắc phục sự cố sản phẩm và DBMS của cartesian. Tôi duy trì quan điểm của mình rằng các phép nối tự nhiên chỉ quan tâm đến học thuật và các DBMS quan trọng như SQL Server không cố ý thực hiện điều này - thêm một điều kiện rõ ràng dẫn đến hiểu và bảo trì mã tốt hơn. Một câu hỏi liên quan: stackoverflow.com/questions/4826613/natural-join-in-sql-server
Bogdan Gavril MSFT

1
@HLGEM: một người có thể đưa ra các lập luận tương tự chống lại SELECT * FROM...(và có lẽ bạn cũng vậy). Nhưng đó là trong ngôn ngữ, nó có trong mọi triển khai SQL và tôi sử dụng nó thường xuyên (và tôi cá bạn cũng vậy!) Gợi ý không phải tất cả mã đều là mã sản xuất.
onedaywhen ngày

1
Vấn đề thực sự với cột tham gia "tự nhiên" không phải là thay đổi tên mà là thêm tên mới không được xung đột giữa tất cả các bảng có thể được tham gia trong hệ thống. Lấy các cột rất phổ biến như "tên", "mô tả", ... Sử dụng "liên kết tự nhiên" sẽ làm cho chúng được nối ngược lại nó vô nghĩa và hơn thế nữa là trái logic nghiệp vụ và dẫn đến lỗi. Vì vậy, có, "tham gia tự nhiên" là nguy hiểm. Nó buộc bạn phải có các tên riêng biệt ngoại trừ các cột khóa (chính / ngoại) và mất "khoảng cách giữa tên".
LoganMzz

14

Câu trả lời của @ outis rất hay: ngắn gọn và chính xác về quan hệ.

Tuy nhiên, tình hình phức tạp hơn một chút về SQL.

Hãy xem xét các nhà cung cấp và cơ sở dữ liệu bộ phận thông thường nhưng được triển khai trong SQL:

SELECT * FROM S NATURAL JOIN SP;

sẽ trả về tập kết quả ** với các cột

SNO, SNAME, STATUS, CITY, PNO, QTY

Phép nối được thực hiện trên cột có cùng tên trong cả hai bảng , SNO. Lưu ý rằng tập kết quả có sáu cột và chỉ chứa một cột choSNO .

Bây giờ hãy xem xét một eqijoin theta, trong đó tên cột cho phép nối phải được chỉ định rõ ràng (cộng với các biến phạm vi SSPlà bắt buộc):

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

Tập kết quả sẽ có bảy cột, bao gồm hai cột cho SNO. Tên của tập kết quả là những gì mà Tiêu chuẩn SQL gọi là "phụ thuộc vào việc triển khai" nhưng có thể trông giống như sau:

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

hoặc có lẽ điều này

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

Nói cách khác, NATURAL JOINtrong SQL có thể được coi là xoá các cột có tên trùng lặp từ resultset (nhưng than ôi sẽ không loại bỏ các hàng trùng lặp - bạn phải nhớ để thay đổi SELECTđể SELECT DISTINCTcho mình).


** Tôi không hoàn toàn biết kết quả của SELECT * FROM table_expression;nó là gì. Tôi biết nó không phải là một mối quan hệ bởi vì, trong số các lý do khác, nó có thể có các cột có tên trùng lặp hoặc một cột không có tên. Tôi biết nó không phải là một tập hợp bởi vì, trong số các lý do khác, thứ tự cột là quan trọng. Nó thậm chí không phải là một bảng SQL hoặc biểu thức bảng SQL. Tôi gọi nó là một tập kết quả.


Cũng vậy JOIN ... USING(...).
Benoit

Tại sao bạn nói "Tôi không biết kết quả SELECT * FROM table_expression;" ?
Pacerier

@Pacerier: ờ, vì tôi không biết nó là gì! Lần trước khi tôi xem xét, Tiêu chuẩn SQL đã tránh xác định nó là gì. Tôi không biết nó không phải là gì (không phải quan hệ, không phải tập hợp, không phải bảng, không phải biểu thức bảng). Vì vậy, để dễ tham khảo, tôi đã sử dụng thuật ngữ của riêng mình, 'resultset'. Lưu ý rằng trong mô hình quan hệ, kết quả của một phép toán liên quan đến hai quan hệ là một quan hệ. Không thể thực hiện câu lệnh tương đương cho SQL AFAIK.
ngày

11

Natural là tập con của Equi là tập con của Theta.

Nếu tôi sử dụng dấu = trên một phép nối theta thì nó có giống hệt như việc tôi chỉ sử dụng một phép nối tự nhiên không ???

Không nhất thiết, nhưng nó sẽ là một Trang bị. Tự nhiên có nghĩa là bạn đang khớp trên tất cả các cột có tên tương tự, Trang bị chỉ có nghĩa là bạn đang sử dụng '=' độc quyền (và không phải 'nhỏ hơn', như, v.v.)

Tuy nhiên, đây chỉ là học thuật thuần túy, bạn có thể làm việc với cơ sở dữ liệu quan hệ trong nhiều năm và không bao giờ nghe thấy bất kỳ ai sử dụng các thuật ngữ này.


Tôi nghi ngờ rằng khi bạn nói "cơ sở dữ liệu quan hệ", tôi nghi ngờ bạn có ý khác, ví dụ: "SQL".
onedaywhen

Làm việc không phải học thuật với cơ sở dữ liệu quan hệ không phải là SQL? Vậy ý bạn là sản phẩm nào?
onedaywhen

3
Trong đại số ban đầu của Codd, phép nối tự nhiên là loại phép nối cơ bản trong khi phép nối tương đương hoặc theta- là viết tắt của một NJ (ví dụ: tích chéo) theo sau là một giới hạn. "Natural là một tập con của Equi là một tập con của Theta" có lẽ điều đó có nghĩa là mọi NJ cũng có thể được biểu thị dưới dạng EJ hoặc TJ. Tôi cho rằng điều đó đúng nếu σ 1 = 1 (A x B) được tính là tương đương, trong trường hợp đó mọi phép toán của đại số quan hệ có thể được biểu diễn dưới dạng tương đương ở dạng đó. Sự mơ hồ ở đây là có thể có nhiều hơn một tập hợp các toán tử cơ bản cho RA.
nvogel

2
@EricFail: sqlvogel chỉ trích dẫn câu trả lời của kekekela, chứ không phải bất cứ thứ gì từ Codd. Nếu bạn muốn biết thêm về các bài viết của Codd về phép nối (θ hoặc cách khác), bạn có thể thử "Mô hình quan hệ để quản lý cơ sở dữ liệu", hoặc làm theo cách của bạn thông qua thư mục của anh ấy .
outis

1
... Câu hỏi bạn liên kết đến có câu trả lời gần với những gì bạn đang tìm kiếm, có thể càng gần càng tốt. Nó liên kết với sự hoàn chỉnh quan hệ của ngôn ngữ con cơ sở dữ liệu . P. 10 mô tả mối liên hệ giữa các phép nối θ, = và các phép nối tự nhiên (mặc dù các phép nối tự nhiên không hoàn toàn là các tập con của = trong công thức của Codd, mà là phép chiếu của = -joins).
outis

7

Theta Join: Khi bạn thực hiện một truy vấn cho phép nối bằng cách sử dụng bất kỳ toán tử nào, (ví dụ: =, <,>,> =, v.v.), thì truy vấn nối đó xuất hiện trong phép nối Theta.

Trang bị Tham gia: Khi bạn thực hiện truy vấn tham gia chỉ sử dụng toán tử bình đẳng, thì truy vấn tham gia đó nằm trong Tham gia trang bị.

Thí dụ:

> CHỌN * TỪ Bộ phận Emp JOIN ON Emp.DeptID = Dept.DeptID;
> CHỌN * TỪ Emp INNER THAM GIA Dept USING (DeptID)
Điều này sẽ hiển thị:
 _________________________________________________
| Emp.Name | Emp.DeptID | Dept.Name | Dept.DeptID |
| | | | |

Lưu ý: Tham gia trang bị cũng là tham gia theta!

Natural Join: một loại Equi Join diễn ra ngầm bằng cách so sánh tất cả các cột cùng tên trong cả hai bảng.

Lưu ý: ở đây, kết quả nối chỉ có một cột cho mỗi cặp cột được đặt tên giống nhau.

Thí dụ

 CHỌN * TỪ Emp NATURAL JOIN Dept
Điều này sẽ hiển thị:
 _______________________________
| DeptID | Emp.Name | Dept.Name |
| | | |

1

Tích Descartes của hai bảng cho tất cả các kết hợp có thể có của các bộ giá trị như ví dụ trong toán học là tích chéo của hai tập hợp. vì đôi khi có một số giá trị rác cũng chiếm không gian không cần thiết trong bộ nhớ, vì vậy ở đây các phép tham gia giải cứu đưa ra sự kết hợp của chỉ những giá trị thuộc tính được yêu cầu và có ý nghĩa.

phép nối bên trong cung cấp cho trường lặp lại trong bảng hai lần trong khi phép nối tự nhiên ở đây giải quyết vấn đề bằng cách chỉ lọc các cột lặp lại và hiển thị nó chỉ một lần. ví dụ, cả hai đều hoạt động như nhau. phép nối tự nhiên hiệu quả hơn vì nó bảo toàn bộ nhớ. Ngoài ra, các phần dư thừa được loại bỏ trong phép nối tự nhiên.

Phép nối tương đương của hai bảng sao cho chúng chỉ hiển thị những bộ giá trị khớp với giá trị trong bảng khác. ví dụ: cho new1 và new2 là hai bảng. nếu truy vấn sql chọn * từ new1 tham gia new2 trên new1.id = new.id (id là cùng một cột trong hai bảng) thì hãy bắt đầu từ bảng new2 và tham gia khớp với id trong bảng thứ hai. ngoài ra, phép nối non-equi không có toán tử bình đẳng mà chúng có <,> và toán tử giữa.

phép nối theta bao gồm tất cả các toán tử so sánh bao gồm cả đẳng thức và các toán tử so sánh <,> khác. khi nó sử dụng toán tử bình đẳng (=), nó được gọi là tham gia tương đương.


0

Phép nối tự nhiên: Phép nối tự nhiên có thể thực hiện được khi có ít nhất một thuộc tính chung trong hai quan hệ.

Theta Join: Theta join có thể có khi cả hai cùng hành động với một điều kiện cụ thể.

Tham gia trang bị: Trang bị có thể có khi cả hai hành động với điều kiện công bằng. Nó là một loại tham gia theta.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.