Sự khác biệt giữa tham gia tự nhiên và tham gia bên trong là gì?
Sự khác biệt giữa tham gia tự nhiên và tham gia bên trong là gì?
Câu trả lời:
Một sự khác biệt đáng kể giữa INNER THAM GIA và THAM GIA TỰ NHIÊN là số lượng cột được trả về.
Xem xét:
TableA TableB
+------------+----------+ +--------------------+
|Column1 | Column2 | |Column1 | Column3 |
+-----------------------+ +--------------------+
| 1 | 2 | | 1 | 3 |
+------------+----------+ +---------+----------+
Bảng INNER JOIN
TableA và TableB trên Cột1 sẽ trả về
SELECT * FROM TableA AS a INNER JOIN TableB AS b USING (Column1);
SELECT * FROM TableA AS a INNER JOIN TableB AS b ON a.Column1 = b.Column1;
+------------+-----------+---------------------+
| a.Column1 | a.Column2 | b.Column1| b.Column3|
+------------------------+---------------------+
| 1 | 2 | 1 | 3 |
+------------+-----------+----------+----------+
Bảng NATURAL JOIN
TableA và TableB trên Cột1 sẽ trả về:
SELECT * FROM TableA NATURAL JOIN TableB
+------------+----------+----------+
|Column1 | Column2 | Column3 |
+-----------------------+----------+
| 1 | 2 | 3 |
+------------+----------+----------+
Cột lặp lại được tránh.
(AFAICT từ ngữ pháp chuẩn, bạn không thể chỉ định các cột tham gia trong một phép nối tự nhiên; phép nối này hoàn toàn dựa trên tên. Xem thêm Wikipedia .)
( Có một cheat trong liên kết nội đầu ra; các a.
và b.
phụ tùng sẽ không có trong tên cột, bạn sẽ chỉ có column1
, column2
, column1
, column3
như các tiêu đề. )
NATURAL JOIN
sẽ hủy hoại, tại sao nó bất ngờ, và bạn đang ở thế giới nào?
Customers
và Employees
, tham gia vào EmployeeID
. Employees
cũng có một ManagerID
lĩnh vực. Mọi thứ đều ổn. Sau đó, một ngày nào đó, một người nào đó thêm một ManagerID
lĩnh vực vào Customers
bàn. Sự tham gia của bạn sẽ không bị phá vỡ (đó sẽ là một sự thương xót), thay vào đó giờ đây nó sẽ bao gồm một trường thứ hai và hoạt động không chính xác . Do đó, một sự thay đổi dường như vô hại có thể phá vỡ một cái gì đó chỉ liên quan đến xa. RẤT TỆ. Mặt trái duy nhất của một phép nối tự nhiên là tiết kiệm một chút gõ và nhược điểm là đáng kể.
SELECT * FROM TableA INNER JOIN TableB USING (Column1)
đưa ra 4 cột. Điều này không đúng vì SELECT * FROM TableA INNER JOIN TableB USING (Column1)
và SELECT * FROM TableA NATURAL JOIN TableB
bằng nhau, cả hai đều cho 3 cột.
natural left
hoặc natural right
) giả định tiêu chí tham gia là nơi các cột có cùng tên trong cả hai bảng khớpTôi sẽ tránh sử dụng các phép nối tự nhiên như bệnh dịch hạch, bởi vì các phép nối tự nhiên là:
NATURAL JOIN Checkouts
chỉ có thể có khi các quy ước đặt tên cơ sở dữ liệu là chính thức và được thi hành ...."
id
có mặt ở khắp nơi và vô dụng để tham gia; tên khóa nước ngoài thông thường là tablename_id
. Tham gia tự nhiên là một ý tưởng tồi, xấu, xấu.
Một phép nối tự nhiên chỉ là một phím tắt để tránh gõ, với giả định rằng phép nối này đơn giản và khớp với các trường cùng tên.
SELECT
*
FROM
table1
NATURAL JOIN
table2
-- implicitly uses `room_number` to join
Giống như ...
SELECT
*
FROM
table1
INNER JOIN
table2
ON table1.room_number = table2.room_number
Tuy nhiên, những gì bạn không thể làm với định dạng phím tắt là tham gia phức tạp hơn ...
SELECT
*
FROM
table1
INNER JOIN
table2
ON (table1.room_number = table2.room_number)
OR (table1.room_number IS NULL AND table2.room_number IS NULL)
NATURAL JOIN ... USING ()
? Tiêu chuẩn là a NATURAL JOIN b
hoặca JOIN b USING (c)
room_number
, trong khi các phép nối bên trong của bạn sẽ có hai cột được đặt tên room_number
.
SQL không trung thành với mô hình quan hệ theo nhiều cách. Kết quả của một truy vấn SQL không phải là một mối quan hệ vì nó có thể có các cột có tên trùng lặp, cột 'ẩn danh' (không tên), hàng trùng lặp, null, v.v. SQL không coi các bảng là quan hệ vì nó phụ thuộc vào thứ tự cột, v.v.
Ý tưởng đằng sau NATURAL JOIN
trong SQL là làm cho nó dễ dàng trung thành hơn với mô hình quan hệ. Kết quả của NATURAL JOIN
hai bảng sẽ có các cột được nhân đôi theo tên, do đó không có cột ẩn danh. Tương tự, UNION CORRESPONDING
và EXCEPT CORRESPONDING
được cung cấp để giải quyết sự phụ thuộc của SQL vào thứ tự cột trong UNION
cú pháp kế thừa .
Tuy nhiên, như với tất cả các kỹ thuật lập trình, nó đòi hỏi kỷ luật phải hữu ích. Một yêu cầu để thành công NATURAL JOIN
là các cột được đặt tên nhất quán, bởi vì các phép nối được ngụ ý trên các cột có cùng tên (điều đáng tiếc là cú pháp đổi tên cột trong SQL là dài dòng nhưng tác dụng phụ là khuyến khích kỷ luật khi đặt tên cột trong bảng cơ sở và VIEW
s :)
Lưu ý rằng SQL NATURAL JOIN
là một đẳng thức **, tuy nhiên điều này không có ích gì. Hãy xem xét rằng nếu NATURAL JOIN
là loại tham gia duy nhất được hỗ trợ trong SQL thì nó vẫn hoàn toàn tương đối .
Mặc dù thực sự là bất kỳ NATURAL JOIN
có thể được viết bằng cách sử dụng INNER JOIN
và chiếu ( SELECT
), nhưng cũng đúng là bất kỳ INNER JOIN
có thể được viết bằng cách sử dụng sản phẩm ( CROSS JOIN
) và hạn chế ( WHERE
); lưu ý thêm rằng NATURAL JOIN
giữa các bảng không có tên cột chung sẽ cho kết quả giống như CROSS JOIN
. Vì vậy, nếu bạn chỉ quan tâm đến kết quả là quan hệ (và tại sao không bao giờ?!) Thì đây NATURAL JOIN
là loại tham gia duy nhất bạn cần. Chắc chắn, sự thật là từ góc độ thiết kế ngôn ngữ như viết tắt INNER JOIN
và CROSS JOIN
có giá trị của chúng, nhưng cũng xem xét rằng hầu như mọi truy vấn SQL đều có thể được viết bằng 10 cách khác nhau về mặt cú pháp, nhưng tương đương về mặt ngữ nghĩa và đây là điều khiến cho việc tối ưu hóa SQL rất khó khăn phát triển.
Dưới đây là một số truy vấn mẫu (sử dụng cơ sở dữ liệu bộ phận và nhà cung cấp thông thường ) tương đương về mặt ngữ nghĩa:
SELECT *
FROM S NATURAL JOIN SP;
-- Must disambiguate and 'project away' duplicate SNO attribute
SELECT S.SNO, SNAME, STATUS, CITY, PNO, QTY
FROM S INNER JOIN SP
USING (SNO);
-- Alternative projection
SELECT S.*, PNO, QTY
FROM S INNER JOIN SP
ON S.SNO = SP.SNO;
-- Same columns, different order == equivalent?!
SELECT SP.*, S.SNAME, S.STATUS, S.CITY
FROM S INNER JOIN SP
ON S.SNO = SP.SNO;
-- 'Old school'
SELECT S.*, PNO, QTY
FROM S, SP
WHERE S.SNO = SP.SNO;
** Tham gia tự nhiên quan hệ không phải là một Equijoin, nó là một hình chiếu của một. - philipxy
Tham NATURAL
gia chỉ là một cú pháp ngắn cho một liên kết cụ thể INNER
- hoặc "tham gia đẳng thức" - và, một khi cú pháp được mở ra, cả hai đều đại diện cho cùng một hoạt động Đại số quan hệ. Đây không phải là "loại khác nhau" của tham gia, như với trường hợp OUTER
( LEFT
/ RIGHT
) hoặc CROSS
tham gia.
Xem phần bình đẳng trên Wikipedia:
Một phép nối tự nhiên cung cấp một sự chuyên môn hóa hơn nữa của đẳng thức. Vị từ nối phát sinh ngầm bằng cách so sánh tất cả các cột trong cả hai bảng có cùng tên cột trong các bảng đã nối. Bảng tham gia kết quả chỉ chứa một cột cho mỗi cặp cột được đặt tên bằng nhau.
Hầu hết các chuyên gia đồng ý rằng THAM GIA TỰ NHIÊN là nguy hiểm và do đó không khuyến khích sử dụng chúng. Sự nguy hiểm đến từ việc vô tình thêm một cột mới, được đặt tên giống như một cột khác ...
Đó là, tất cả các phép NATURAL
nối có thể được viết dưới dạng phép INNER
nối (nhưng điều ngược lại là không đúng). Để làm như vậy, chỉ cần tạo vị ngữ một cách rõ ràng - ví dụ USING
hoặc ON
- và, như Jonathan Leffler đã chỉ ra, chọn các cột tập kết quả mong muốn để tránh "trùng lặp" nếu muốn.
Chúc mừng mã hóa.
( NATURAL
Từ khóa cũng có thể được áp dụng LEFT
và RIGHT
tham gia, và áp dụng tương tự. Tham NATURAL LEFT/RIGHT
gia chỉ là một cú pháp ngắn cho một tham gia cụ thể LEFT/RIGHT
.)
Tham gia tự nhiên: Đó là kết quả hoặc kết hợp của tất cả các cột trong hai bảng. Nó sẽ trả về tất cả các hàng của bảng đầu tiên đối với bảng thứ hai.
Tham gia bên trong: Tham gia này sẽ hoạt động trừ khi có bất kỳ tên cột nào được sxame trong hai bảng
Một tham gia tự nhiên là nơi 2 bảng được nối trên cơ sở của tất cả các cột phổ biến.
cột chung: là một cột có cùng tên trong cả hai bảng + có kiểu dữ liệu tương thích trong cả hai bảng. Bạn chỉ có thể sử dụng = toán tử
Tham gia bên trong là nơi 2 bảng được nối trên cơ sở các cột phổ biến được đề cập trong mệnh đề ON.
cột chung: là một cột có các kiểu dữ liệu tương thích trong cả hai bảng nhưng không cần phải có cùng tên. Bạn có thể chỉ sử dụng bất kỳ nhà điều hành so sánh như =
, <=
, >=
, <
, >
,<>
sự khác biệt là tham gia bên trong (đẳng thức / mặc định) và tham gia tự nhiên mà trong phần chung của cột tham gia natuarl sẽ được hiển thị trong một lần duy nhất nhưng bên trong / đẳng thức / mặc định / đơn giản, cột chung sẽ được hiển thị gấp đôi thời gian.
Tham gia bên trong và tham gia tự nhiên gần như giống nhau nhưng có một chút khác biệt giữa chúng. Sự khác biệt là trong phép nối tự nhiên không cần chỉ định điều kiện nhưng trong điều kiện nối bên trong là bắt buộc. Nếu chúng ta chỉ định điều kiện trong phép nối bên trong, thì các bảng kết quả giống như một sản phẩm cartesian.
mysql> SELECT * FROM tb1 ;
+----+------+
| id | num |
+----+------+
| 6 | 60 |
| 7 | 70 |
| 8 | 80 |
| 1 | 1 |
| 2 | 2 |
| 3 | 3 |
+----+------+
6 rows in set (0.00 sec)
mysql> SELECT * FROM tb2 ;
+----+------+
| id | num |
+----+------+
| 4 | 40 |
| 5 | 50 |
| 9 | 90 |
| 1 | 1 |
| 2 | 2 |
| 3 | 3 |
+----+------+
6 rows in set (0.00 sec)
THAM GIA
mysql> SELECT * FROM tb1 JOIN tb2 ;
+----+------+----+------+
| id | num | id | num |
+----+------+----+------+
| 6 | 60 | 4 | 40 |
| 7 | 70 | 4 | 40 |
| 8 | 80 | 4 | 40 |
| 1 | 1 | 4 | 40 |
| 2 | 2 | 4 | 40 |
| 3 | 3 | 4 | 40 |
| 6 | 60 | 5 | 50 |
| 7 | 70 | 5 | 50 |
| 8 | 80 | 5 | 50 |
.......more......
return 36 rows in set (0.01 sec)
AND NATURAL JOIN :
mysql> SELECT * FROM tb1 NATURAL JOIN tb2 ;
+----+------+
| id | num |
+----+------+
| 1 | 1 |
| 2 | 2 |
| 3 | 3 |
+----+------+
3 rows in set (0.01 sec)
Tham gia bên trong, tham gia hai bảng trong đó tên cột giống nhau.
Tham gia tự nhiên, tham gia hai bảng trong đó tên cột và kiểu dữ liệu giống nhau.