Perbedaan antara natural join dan inner join

197

Apa perbedaan antara gabungan alami dan gabungan batin?

pandai besi
sumber
3
Pertanyaan ini bukan duplikat dari yang lain, karena ini adalah tentang INNER vs NATURAL bergabung, yang tidak dibahas di yang lain.
1
Pada suatu waktu, ini ditutup sebagai duplikat dari Apa perbedaan antara gabungan kiri, kanan, luar dan dalam , tetapi pertanyaan itu tidak membahas perbedaan antara sambungan dalam dan sambungan alami.
Jonathan Leffler

Jawaban:

250

Satu perbedaan signifikan antara INNER JOIN dan NATURAL JOIN adalah jumlah kolom yang dikembalikan.

Mempertimbangkan:

TableA                           TableB
+------------+----------+        +--------------------+    
|Column1     | Column2  |        |Column1  |  Column3 |
+-----------------------+        +--------------------+
| 1          |  2       |        | 1       |   3      |
+------------+----------+        +---------+----------+

The INNER JOINdari TableA dan TableB di Column1 akan kembali

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

The NATURAL JOINdari TableA dan TableB di Column1 akan kembali:

SELECT * FROM TableA NATURAL JOIN TableB
+------------+----------+----------+    
|Column1     | Column2  | Column3  |
+-----------------------+----------+
| 1          |  2       |   3      |
+------------+----------+----------+

Kolom yang berulang dihindari.

(AFAICT dari tata bahasa standar, Anda tidak bisa menentukan kolom bergabung dalam gabungan alami; gabungan itu berdasarkan nama. Lihat juga Wikipedia .)

( Ada cheat di bergabung dalam output; yang a.dan b.bagian tidak akan berada dalam nama kolom, Anda baru saja memiliki column1, column2, column1, column3sebagai judul. )

Jonathan Leffler
sumber
2
Saya memiliki dua tabel TableA (Column1, Column2) dan TableB (Column2, Column3).
2 8
16
Kolaps kolom dalam output adalah aspek yang paling tidak penting dari gabungan natural. Hal-hal yang perlu Anda ketahui adalah (A) secara otomatis bergabung di bidang dengan nama yang sama dan (B) itu akan mengacaukan pantat Anda ketika Anda tidak menduganya. Di dunia saya, menggunakan gabungan alami adalah alasan untuk pemecatan.
8
@JonofAllTrades Bisakah Anda menjelaskan lebih lanjut tentang apa yang sebenarnya NATURAL JOINakan rusak, mengapa hal itu tidak terduga, dan di dunia apa Anda berada?
Bryson
35
Ini agak ditanggapi dalam jawaban user166390. Katakanlah Anda memiliki gabungan alami antara Customersdan Employees, bergabung EmployeeID. Employeesjuga memiliki ManagerIDbidang. Semuanya baik. Kemudian, suatu hari, seseorang menambahkan ManagerIDbidang ke Customerstabel. Gabung Anda tidak akan rusak (itu akan menjadi rahmat), sebaliknya sekarang akan menyertakan bidang kedua, dan bekerja secara tidak benar . Dengan demikian, perubahan yang tampaknya tidak berbahaya dapat merusak sesuatu yang hanya terkait jarak jauh. SANGAT BURUK. Satu-satunya sisi positif dari gabungan alami adalah menyimpan sedikit pengetikan, dan downside adalah substansial.
2
@ Jonathan, Mengenai jawaban Anda, Anda menyatakan bahwa SELECT * FROM TableA INNER JOIN TableB USING (Column1)memberi 4 kolom. Ini tidak benar karena SELECT * FROM TableA INNER JOIN TableB USING (Column1)dan SELECT * FROM TableA NATURAL JOIN TableBsama, keduanya memberikan 3 kolom.
Pacerier
81
  • Gabungan dalam adalah salah satu tempat baris yang cocok dalam tabel gabungan diperlukan untuk baris dari tabel pertama yang akan dikembalikan
  • Gabungan luar adalah salah satu tempat baris yang cocok dalam tabel gabungan tidak diperlukan untuk baris dari tabel pertama yang akan dikembalikan
  • Sebuah alami bergabung adalah bergabung (Anda dapat memiliki natural leftatau natural right) yang mengasumsikan bergabung kriteria untuk berada di tempat kolom yang sama-nama di kedua pertandingan tabel

Saya akan menghindari penggunaan gabungan alami seperti wabah, karena gabungan alami adalah:

  • bukan standar sql [SQL 92] dan karenanya tidak portabel, tidak dapat dibaca (oleh sebagian besar kode SQL) dan mungkin tidak didukung oleh berbagai alat / pustaka
  • tidak informatif; Anda tidak dapat mengetahui kolom apa yang sedang digabung tanpa merujuk pada skema
  • kondisi bergabung Anda sangat rentan terhadap perubahan skema - jika ada beberapa kolom bergabung alami dan satu kolom tersebut dihapus dari tabel, kueri akan tetap dijalankan, tetapi mungkin tidak benar dan perubahan perilaku ini akan diam
  • hampir tidak sepadan dengan usaha; Anda hanya menghemat sekitar 10 detik mengetik
Bohemian
sumber
2
Saya pikir kiri / kanan untuk bagian luar harus disebutkan (karena bagian luar disebutkan sama sekali). Tetapi sebaliknya, bagus dan ringkas: itu hanya melewatkan diagram catatan SQL contoh cantik.
2
KIRI ALAMI dan KANAN ALAMI juga ada. Tapi ya, tetap hindari mereka.
MatBailie
1
@Bohemian, Mengenai "hindari mereka seperti wabah", ada kasus penggunaan nyata untuk penggabungan alami di mana mereka berguna. mariadb.com/kb/en/sql-99/natural-join "..." Buku "yang tampak kasual NATURAL JOIN Checkoutshanya mungkin terjadi ketika konvensi penamaan basis data resmi dan ditegakkan ...."
Pacerier
2
@sqlvovel ada banyak yang salah dengan komentar Anda, khususnya salah. Bergabung dengan kolom tidak dapat "ditentukan dalam daftar pilih". Definisi dari natural join adalah untuk bergabung pada * semua kolom yang diberi nama *. Dari dokumen MySQL: GABUNGAN ALAMI [KIRI] dari dua tabel didefinisikan secara semantik setara dengan GABUNGAN INNER atau GABUNGAN KIRI dengan klausa PENGGUNAAN yang menamai semua kolom yang ada di kedua tabel. . Dan satu hal lagi - dalam praktiknya tidak ada gunanya, karena di idmana-mana dan tidak berguna untuk bergabung; nama kunci asing yang biasa adalah tablename_id. Gabungan alami adalah ide yang buruk, buruk, buruk.
Bohemian
2
Tidak ada kolom ganda yang dikembalikan dalam permintaan saya. Salah satu keuntungan dari semantik NJ adalah kolom yang digandakan tidak pernah dikembalikan. Permintaan Anda sebelumnya juga "kurang aman" daripada milik saya karena akan gagal jika kolom yang disebut "a" ditambahkan ke t2 (karena kondisi gabungan yang tidak disebut alias bersifat ambigu). Saya menduga bahwa prasangka Anda terhadap NJ didasarkan pada kenyataan bahwa Anda belum mencobanya di produk di mana standar SQL didukung dengan benar. Pertanyaannya di sini adalah tentang SQL, bukan MySQL - hal yang sangat berbeda. Anda masih belum mengoreksi jawaban Anda karena tidak standar.
nvogel
27

Gabung alami hanyalah cara pintas untuk menghindari mengetik, dengan anggapan bahwa gabung itu sederhana dan cocok dengan bidang dengan nama yang sama.

SELECT
  *
FROM
  table1
NATURAL JOIN
  table2
    -- implicitly uses `room_number` to join

Sama dengan...

SELECT
  *
FROM
  table1
INNER JOIN
  table2
    ON table1.room_number = table2.room_number

Namun, apa yang tidak dapat Anda lakukan dengan format pintasan adalah penggabungan yang lebih rumit ...

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)
MatBailie
sumber
2
@ JonathanLeffler - Di MySQL, tentu saja.
MatBailie
3
OK - menarik. Saya bertanya karena standar SQL tampaknya tidak mengizinkan ini (tetapi ekstensi selalu memungkinkan).
Jonathan Leffler
Yang DBMS memungkinkan sintaks non-standar ini: NATURAL JOIN ... USING ()? a NATURAL JOIN ba JOIN b USING (c)
Standarnya
1
"hanya jalan pintas untuk menghindari mengetik" adalah pernyataan yang salah. Fitur terpentingnya adalah tidak menghasilkan kolom duplikat.
onedaywhen
... misalnya, hasil kueri Anda yang menggunakan gabungan alami hanya akan memiliki satu kolom bernama room_number, sedangkan gabungan batin Anda akan memiliki dua kolom bernama room_number.
onedaywhen
13

SQL tidak setia pada model relasional dalam banyak hal. Hasil kueri SQL bukan relasi karena mungkin memiliki kolom dengan nama duplikat, kolom 'anonim' (tidak bernama), baris duplikat, nol, dll. SQL tidak memperlakukan tabel sebagai relasi karena bergantung pada pemesanan kolom, dll.

Gagasan NATURAL JOINdi balik dalam SQL adalah untuk membuatnya lebih mudah untuk lebih setia pada model relasional. Hasil dari NATURAL JOINdua tabel akan memiliki kolom diduplikasi oleh nama, maka tidak ada kolom anonim. Demikian pula, UNION CORRESPONDINGdan EXCEPT CORRESPONDINGdisediakan untuk mengatasi ketergantungan SQL pada pemesanan kolom dalam warisanUNION sintaks .

Namun, seperti halnya semua teknik pemrograman, diperlukan disiplin agar bermanfaat. Salah satu persyaratan untuk sukses NATURAL JOINadalah kolom yang secara konsisten dinamai, karena gabungan tersirat pada kolom dengan nama yang sama (ini memalukan bahwa sintaks untuk mengganti nama kolom dalam SQL adalah verbose tetapi efek sampingnya adalah mendorong disiplin ketika memberi nama kolom pada tabel dasar dan VIEWs :)

Catatan SQL NATURAL JOINadalah equi-join **, namun ini bukan bilah kegunaan. Pertimbangkan bahwa jika NATURAL JOINhanya tipe join yang didukung dalam SQL, itu akan tetap lengkap secara relasional .

Meskipun memang benar bahwa ada yang NATURAL JOINdapat ditulis menggunakan INNER JOINdan proyeksi ( SELECT), juga benar bahwa ada yang INNER JOINdapat ditulis menggunakan produk ( CROSS JOIN) dan pembatasan ( WHERE); Perhatikan lebih lanjut bahwa NATURAL JOINantara tabel tanpa nama kolom yang sama akan memberikan hasil yang sama dengan CROSS JOIN. Jadi, jika Anda hanya tertarik pada hasil yang berhubungan (dan mengapa tidak ?!) maka NATURAL JOINadalah satu-satunya jenis bergabung yang Anda butuhkan. Memang benar bahwa dari perspektif desain bahasa, singkatan seperti INNER JOINdanCROSS JOIN memiliki nilai mereka, tetapi juga mempertimbangkan bahwa hampir semua permintaan SQL dapat ditulis dalam 10 sintaksis yang berbeda, tetapi secara semantik setara, cara dan inilah yang membuat pengoptimal SQL sangat sulit mengembangkan.

Berikut adalah beberapa contoh kueri (menggunakan database suku cadang dan pemasok biasa ) yang secara semantik setara:

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;

** Gabung natural relasional bukan equijoin, ini adalah proyeksi satu. - philipxy

suatu hari nanti
sumber
Join natural relasional bukan equijoin, ini adalah proyeksi satu. SQL natural join adalah SQL equijoin (kemungkinan rangkap) - itu didefinisikan dalam hal penggunaan gabungan dalam.
philipxy
@ philipxy: Terima kasih, saya telah membuat amandemen. Silakan mengedit - ini atau salah satu jawaban saya - untuk salah saji dan kesalahpahaman. Saya masih belajar dari Anda :)
onedaywhen
9

Sebuah NATURALbergabung hanya sintaks singkat untuk tertentu INNER bergabung - atau "equi-join" - dan, sekali sintaks yang terbuka, baik mewakili Relational Aljabar operasi yang sama. Ini bukan "jenis yang berbeda" dari bergabung, seperti halnya dengan OUTER( LEFT/ RIGHT) atau CROSSbergabung.

Lihat bagian gabung equi di Wikipedia:

Gabungan alami menawarkan spesialisasi lebih lanjut dari equi-joins. Predikat gabungan muncul secara implisit dengan membandingkan semua kolom di kedua tabel yang memiliki nama kolom yang sama di tabel gabungan .Tabel gabungan yang dihasilkan hanya berisi satu kolom untuk setiap pasangan kolom dengan nama sama.

Sebagian besar ahli sepakat bahwa GABUNGAN ALAMI berbahaya dan karenanya sangat tidak menganjurkan penggunaannya. Bahayanya datang dari tidak sengaja menambahkan kolom baru, dinamai sama dengan kolom lain ...

Artinya, semua NATURALbergabung dapat ditulis sebagai INNERbergabung (tapi sebaliknya tidak benar). Untuk melakukannya, buat saja predikat secara eksplisit - misalnya USINGatauON - dan, seperti yang ditunjukkan Jonathan Leffler, pilih kolom set hasil yang diinginkan untuk menghindari "duplikat" jika diinginkan.

Selamat coding.


(Kata NATURALkunci juga dapat diterapkan LEFTdan RIGHTbergabung, dan hal yang sama berlaku. NATURAL LEFT/RIGHTGabungan hanyalah sintaks pendek untuk gabungan tertentu LEFT/RIGHT .)

Komunitas
sumber
2
"Gabung ALAMI hanyalah sintaks pendek untuk [terpotong]" gabung-equi "- dan, setelah sintaks dibuka, keduanya mewakili Aljabar Relasional yang sama" - Anda benar: itu benar dari aljabar relasional tetapi jawaban Anda rusak setelah itu misalnya "Kebanyakan ahli setuju bahwa GABUNGAN ALAMI berbahaya dan karena itu sangat mengecilkan penggunaannya" - yang para ahli dalam aljabar relasional katakan itu ?!
onedaywhen
2

Natural Join: Ini adalah hasil kombinasi atau gabungan dari semua kolom dalam dua tabel. Ini akan mengembalikan semua baris dari tabel pertama sehubungan dengan tabel kedua.

Gabung Dalam: Gabung ini akan berfungsi kecuali jika salah satu dari nama kolom harus sama dalam dua tabel

Victor Bhatti
sumber
3
Saya tidak berpikir jawaban Anda cukup jelas dan akan membutuhkan penulisan ulang besar untuk memperbaikinya.
onedaywhen
0

Gabung Alami adalah tempat 2 tabel digabungkan berdasarkan semua kolom umum.

Kolom umum: adalah kolom yang memiliki nama yang sama di kedua tabel + memiliki tipe data yang kompatibel di kedua tabel. Anda hanya dapat menggunakan = operator

Inner Join adalah tempat 2 tabel digabungkan berdasarkan kolom umum yang disebutkan dalam klausa ON.

Kolom umum: adalah kolom yang memiliki tipe data yang kompatibel di kedua tabel tetapi tidak perlu memiliki nama yang sama. Anda dapat menggunakan hanya setiap operator perbandingan seperti =, <=, >=, <, >,<>

Suchitra Phadke
sumber
-2

Perbedaannya adalah bahwa di bagian dalam (equi / default) bergabung dan alami bergabung bahwa di kolom umum bergabung natuarl menang akan ditampilkan dalam satu waktu tetapi dalam / equi / default / sederhana bergabung kolom umum akan ditampilkan dua kali.

Rajat Gupta
sumber
-2

Gabung dalam dan gabung alami hampir sama tetapi ada sedikit perbedaan di antara mereka. Perbedaannya adalah pada natural join tidak perlu menentukan kondisi tetapi pada kondisi inner join adalah wajib. Jika kita menentukan kondisi dalam gabungan dalam, tabel yang dihasilkannya seperti produk kartesius.

ruam
sumber
Mengapa tidak perlu menentukan persyaratan bergabung? Dalam keadaan apa kondisi tertentu dalam suatu gabungan akan menghasilkan sesuatu seperti produk kartesius?
onedaywhen
Memanggil gabungan luar dan dalam "hampir sama" adalah pernyataan yang agak meremehkan .. mungkin Anda bisa menguraikan evaluasi Anda?
TMOTTM
-3
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)

INNER BERGABUNG:

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)
zloctb
sumber
-4

Gabung dalam, gabung dua tabel dengan nama kolom yang sama.

Gabung secara alami, gabung dua tabel dengan nama kolom dan tipe data yang sama.

Tejeshwar
sumber
Ini sepenuhnya salah. A NATURAL JOIN(seperti yang ditunjukkan beberapa orang bertahun-tahun yang lalu) adalah nama kolom yang sama. Tipe data tidak harus sama. Bidang yang digunakan untuk INNER JOINkebutuhan tidak memiliki nama yang sama.