it-swarm.asia

Mengapa pencocokan kunci utama / kunci asing tidak digunakan untuk bergabung?

Sejauh yang saya dapat temukan banyak DBMS (mis. Mysql, postgres, mssql) menggunakan kombinasi fk dan pk hanya untuk membatasi perubahan pada data, tetapi jarang digunakan untuk secara otomatis memilih kolom yang akan bergabung (seperti join natural dengan nama). Mengapa demikian? Jika Anda sudah mendefinisikan hubungan antara 2 tabel dengan pk/fk, mengapa basis data tidak dapat mengetahui bahwa jika saya bergabung dengan tabel tersebut, saya ingin bergabung dengan mereka di kolom pk/fk?

EDIT: untuk sedikit memperjelas ini:

misalkan saya punya table1 dan table2. table1 satu memiliki kunci asing pada kolom a, yang merujuk ke kunci utama pada table2, kolom b. Sekarang jika saya bergabung dengan tabel ini, saya harus melakukan sesuatu seperti ini:

SELECT * FROM table1
JOIN table2 ON table1.a = table2.b

Namun, saya sudah mendefinisikan menggunakan kunci saya bahwa table1.a merujuk ke table2.b, jadi bagi saya sepertinya tidak sulit untuk membuat sistem DBMS secara otomatis menggunakan table1.a dan table2.b sebagai kolom gabungan, sehingga orang hanya dapat menggunakan:

SELECT * FROM table1
AUTO JOIN table2

Namun, banyak DBMS tampaknya tidak mengimplementasikan sesuatu seperti ini.

49
Tiddo

Dalam banyak kasus, ada lebih dari satu cara untuk bergabung dengan dua tabel; Lihat jawaban lain untuk banyak contoh. Tentu saja, orang bisa mengatakan bahwa itu akan menjadi kesalahan untuk menggunakan 'join otomatis' dalam kasus-kasus itu. Maka hanya segelintir kasus sederhana di mana dapat digunakan akan ditinggalkan.

Namun, ada kekurangan parah! Kueri yang benar hari ini, mungkin menjadi kesalahan besok hanya dengan menambahkan FK kedua ke tabel yang sama!

Izinkan saya mengatakan itu lagi: dengan menambahkan kolom, kueri yang tidak menggunakan kolom tersebut dapat berubah dari 'benar' menjadi 'kesalahan'!

Itu adalah mimpi buruk pemeliharaan, bahwa setiap panduan gaya waras akan melarang untuk menggunakan fitur ini. Kebanyakan sudah melarang select * untuk alasan yang sama!

Semua ini akan dapat diterima, jika kinerja akan ditingkatkan. Namun, bukan itu masalahnya.

Meringkas, fitur ini hanya dapat digunakan dalam sejumlah kasus sederhana, tidak meningkatkan kinerja, dan sebagian besar panduan gaya akan melarang penggunaannya.

Oleh karena itu tidak mengejutkan bahwa sebagian besar vendor database memilih untuk menghabiskan waktu mereka pada hal-hal yang lebih penting.

32
Sjoerd

Kunci asing dimaksudkan untuk membatasi data. yaitu menegakkan integritas referensial. Itu dia. Tidak ada lagi.

  1. Anda dapat memiliki beberapa kunci asing ke tabel yang sama. Pertimbangkan hal-hal berikut di mana pengiriman memiliki titik awal, dan titik akhir.

    table: USA_States
    StateID
    StateName
    
    table: Shipment
    ShipmentID
    PickupStateID Foreign key
    DeliveryStateID Foreign key
    

    Anda mungkin ingin bergabung berdasarkan status pengambilan. Mungkin Anda ingin bergabung dengan negara pengiriman. Mungkin Anda ingin melakukan 2 gabung untuk keduanya! Mesin sql tidak memiliki cara untuk mengetahui apa yang Anda inginkan.

  2. Anda akan sering bergabung dengan nilai skalar. Meskipun skalar biasanya merupakan hasil perhitungan menengah, kadang-kadang Anda akan memiliki tabel tujuan khusus dengan tepat 1 catatan. Jika mesin mencoba mendeteksi kunci foriegn untuk bergabung .... itu tidak masuk akal karena bergabung silang tidak pernah cocok dengan kolom.

  3. Dalam beberapa kasus khusus, Anda akan bergabung di kolom yang tidak unik. Oleh karena itu keberadaan PK/FK di kolom-kolom itu tidak mungkin.

  4. Anda mungkin berpikir poin 2 dan 3 di atas tidak relevan karena pertanyaan Anda tentang kapan --- ADALAH hubungan PK/FK tunggal antar tabel. Namun kehadiran PK/FK tunggal di antara tabel tidak berarti Anda tidak dapat memiliki bidang lain untuk bergabung selain PK/FK. Mesin sql tidak akan tahu bidang mana yang ingin Anda ikuti.

  5. Katakanlah Anda memiliki tabel "USA_States", dan 5 tabel lainnya dengan FK ke negara bagian. Tabel "lima" juga memiliki beberapa kunci asing satu sama lain. Haruskah mesin sql secara otomatis bergabung dengan tabel "lima" dengan "USA_States"? Atau haruskah itu bergabung dengan "lima" satu sama lain? Kedua? Anda bisa mengatur hubungan sehingga mesin sql memasuki loop tak terbatas mencoba untuk bergabung bersama. Dalam situasi ini tidak mungkin mesin sql untuk menebak apa yang Anda inginkan.

Singkatnya: PK/FK tidak ada hubungannya dengan gabungan tabel. Mereka adalah hal-hal yang tidak berkaitan yang terpisah. Itu hanya kecelakaan alam yang sering Anda bergabung di kolom PK/FK.

Apakah Anda ingin mesin sql menebak apakah itu gabungan penuh, kiri, kanan, atau dalam? Saya kira tidak. Meskipun itu bisa dibilang dosa yang lebih rendah daripada menebak kolom untuk bergabung.

27
Lord Tydus

konsep "kebersamaan." Hubungan r1 dan r2 dapat digabung jika dan hanya jika atribut dengan nama yang sama memiliki tipe yang sama ... konsep ini berlaku tidak hanya untuk bergabung seperti itu tetapi juga untuk berbagai operasi lainnya [seperti serikat pekerja] juga.

SQL dan Teori Relasional: Cara Menulis Kode SQL yang Akurat Oleh C. J. Date

SQL standar sudah memiliki fitur seperti itu, yang dikenal sebagai NATURAL JOIN, dan telah diterapkan di mySQL.

Meskipun saran Anda tidak cukup layak, tampaknya itu masuk akal. Dengan SQL Server (yang tidak memiliki dukungan untuk NATURAL JOIN ), saya menggunakan SQL Prompt di Management Studio: saat menulis INNER JOIN InteliSensenya menyarankan ON klausa berdasarkan nama atribut umum dan kunci asing dan saya merasa sangat berguna. Saya tidak punya keinginan besar untuk melihat tipe join SQL standar (baru) untuk ini.

11
onedaywhen

SQL yang lebih dulu!

Kunci Asing dan batasan Kunci Asing muncul kemudian dan pada dasarnya adalah optimasi untuk aplikasi gaya "transaksi".

Database relasional pada awalnya dipahami sebagai metode penerapan query kompleks pada set data dengan cara yang secara matematis dapat dibuktikan menggunakan aljabar relasional. YAITU. untuk sekumpulan data dan kueri tertentu, selalu ada satu jawaban yang benar.

Database relasional telah berkembang sejak saat itu, dan ada penggunaan utama sebagai lapisan persistensi untuk sistem transaksional bukan apa yang CODD et. semua dibayangkan.

Namun badan standar ANSI untuk semua tujuan yang saling bertentangan dan politik vendor selalu berusaha untuk mempertahankan sifat-sifat SQL yang "dapat dibuktikan secara matematis".

Jika Anda mengizinkan database untuk menyimpulkan properti gabungan dari data kunci asing "tersembunyi", Anda akan kehilangan properti ini (pertimbangkan ambiguitas jika ada lebih dari satu set kunci asing yang ditentukan).

Juga seorang programmer yang membaca SQL tidak perlu tahu kunci asing apa yang saat ini didefinisikan untuk dua tabel, dan, perlu memeriksa skema database untuk mengetahui apa yang sedang dilakukan query.

9
James Anderson

Anda mungkin beroperasi pada asumsi yang salah. Anda mengatakan 'sejauh yang Anda bisa tahu' tetapi jangan memberikan bukti empiris atau bukti. Jika pk atau fk adalah indeks terbaik untuk kueri, itu akan digunakan. Saya tidak tahu mengapa Anda melihat ini, tetapi dugaan saya adalah pertanyaan yang kurang baik.


Edit sekarang bahwa pertanyaan telah ditulis ulang sepenuhnya: Kasing yang Anda uraikan hanya untuk sekumpulan kueri yang sangat kecil. Bagaimana jika ada 12 tabel yang Bergabung? Bagaimana jika tidak ada FK .... Bahkan jika ada gabung standar pada saya masih akan selalu menentukan gabung hanya untuk keterbacaan. (Saya tidak mau harus melihat data dan kemudian mencoba mencari tahu apa yang sedang bergabung)

Beberapa alat Kueri benar-benar melakukan gabung otomatis untuk Anda kemudian memungkinkan Anda menghapus atau mengedit gabung. Saya pikir Query Builder MS Access melakukan ini.

Terakhir, standar ANSII menyatakan bahwa join harus ditentukan. Itu alasan yang cukup untuk tidak mengizinkannya.

7
Morons

Meskipun Anda telah menetapkan hubungan Kunci Asing itu tidak berarti itu adalah bagaimana Anda ingin bergabung dengan tabel di semua kueri. Ini adalah metode yang paling mungkin untuk bergabung dengan tabel, tetapi ada kasus di mana itu tidak benar.

  • Anda mungkin ingin menggunakan produk Cartesian dari dua tabel atau bagiannya untuk beberapa tujuan.
  • Mungkin ada bidang lain di mana Anda dapat bergabung untuk tujuan lain.
  • Jika Anda bergabung dengan tiga tabel atau lebih, salah satu tabel mungkin terkait dengan dua atau lebih tabel. Dalam hal ini biasanya hanya satu dari hubungan-hubungan FK yang mungkin yang mungkin sesuai dalam permintaan.
7
BillThor

Ada banyak alasan cara database tidak dapat melakukan ini dengan aman, termasuk fakta bahwa menambah/menghapus Kunci Asing akan mengubah arti permintaan pra-tertulis termasuk kueri dalam kode sumber aplikasi. Sebagian besar basis data juga tidak memiliki set Kunci Asing yang baik yang mencakup semua kemungkinan bergabung yang mungkin ingin Anda lakukan. Juga untuk yang lebih baik atau berharga, Kunci Asing sering dihapus untuk mempercepat sistem dan tidak dapat digunakan pada tabel yang dimuat dalam urutan "salah" dari file.

Namun tidak ada alasan mengapa desain kueri alat atau editor teks tidak dapat secara otomatis menyelesaikan bergabung dengan bantuan Kunci Asing dengan cara yang sama seperti yang mereka berikan kepada Anda intellisense pada nama kolom. Anda dapat mengedit kueri jika alat salah dan menyimpan kueri yang sepenuhnya ditentukan. Alat semacam itu juga dapat memanfaatkan konvensi penamaan kolom Kunci Asing oleh nama tabel "induk" dan kolom dengan nama yang sama di tabel induk/anak, dll.

(Istri saya masih tidak dapat memahami perbedaan antara Management Studio dan Sql Server dan berbicara tentang memulai sql server ketika dia memulai studio manajemen!)

3
Ian Ringrose

Alami bergabung dengan "secara otomatis" bergabung pada persamaan kolom umum, tetapi Anda hanya boleh menulis bahwa jika itu yang Anda inginkan berdasarkan pada makna tabel dan hasil yang diinginkan Anda. Tidak ada "secara otomatis" mengetahui bagaimana dua tabel "harus" bergabung atau dengan cara lain apa pun tabel "harus" muncul dalam kueri. Kami tidak perlu tahu kendala untuk kueri. Kehadiran mereka hanya berarti input mungkin terbatas dan, akibatnya, outputnya juga mungkin. Anda dapat mendefinisikan beberapa jenis operator join_on_fk_to_pk yang "otomatis" bergabung dengan batasan yang dinyatakan; tetapi jika Anda ingin makna kueri tetap sama jika hanya kendala yang berubah tetapi bukan makna tabel maka Anda harus mengubah kueri tersebut menjadi tidak gunakan batasan yang baru dinyatakan. Hanya dengan memberikan kueri yang Anda ingin gunakan gabung & kondisi sudah meninggalkan arti yang sama meskipun ada perubahan kendala .

Apa yang menjadi kendala (termasuk PK, FK, UNIK & PERIKSA) tidak memengaruhi arti tabel. Tentu saja, jika makna tabel berubah maka kontraint mungkin berubah. Tetapi jika kendala berubah itu tidak berarti bahwa permintaan harus berubah.

Orang tidak perlu tahu kendala untuk query. Mengetahui kendala berarti kita dapat menggunakan ekspresi lebih lanjut yang tanpa pegangan kendala tidak akan menghasilkan jawaban yang sama. Misalnya mengharapkan melalui UNIQUE bahwa sebuah tabel memiliki satu baris, sehingga kita dapat menggunakannya sebagai skalar. Kueri ini dapat pecah jika kendala diasumsikan tetapi tidak dinyatakan. Tetapi menyatakan batasan yang tidak diasumsikan oleh kueri tidak dapat memecahkannya.

Apakah ada aturan praktis untuk membangun query SQL dari deskripsi yang dapat dibaca manusia?

3
philipxy

Alasannya adalah bahwa ada BAHASA, dan kemudian ada kepala sekolah yang mendasarinya. Bahasa ini jarang dan kurang dalam banyak fitur yang Anda harapkan untuk melihat dalam bahasa tujuan umum. Ini hanyalah fitur Nice yang belum ditambahkan ke bahasa dan mungkin tidak. Itu bukan bahasa mati jadi ada harapan, tapi saya tidak akan optimis.

Seperti yang telah ditunjukkan orang lain, beberapa implementasi menggunakan ekstensi di mana bergabung (kolom) bergabung dengan dua tabel berdasarkan nama kolom umum, yang agak mirip. Tapi itu tidak menyebar luas. Perhatikan bahwa ekstensi ini berbeda dari SELECT * FROM employee NATURAL JOIN department; sintaks yang tidak termasuk cara untuk menentukan kolom mana yang akan digunakan. Tidak bergantung pada hubungan antara tabel, yang membuat mereka tidak dapat diandalkan (sintaks bergabung alami lebih dari ekstensi).

Tidak ada kendala mendasar untuk "tabel gabung dalam PKFK" di mana PKFK adalah kata kunci yang berarti "hubungan kunci asing yang didefinisikan antara dua tabel", mungkin ada masalah dengan beberapa fk ke tabel yang sama, tetapi itu bisa saja menyebabkan kesalahan. Pertanyaannya adalah apakah orang yang merancang bahasa tersebut menganggap bahwa a) ide yang bagus dan b) lebih baik untuk dikerjakan daripada beberapa perubahan bahasa lainnya ...

2
jmoreno

Jika menghilangkan klausa ON diasumsikan mengikuti bidang berdasarkan integritas referensial, bagaimana Anda akan melakukan produk Cartesian?

Edit: using AUTO Kelebihan dari ini adalah mengetik yang kurang dan Anda tidak harus tahu bagaimana mereka bergabung atau ingat bergabung yang rumit. Jika hubungan berubah, itu ditangani secara otomatis, tetapi itu jarang terjadi kecuali dalam pengembangan awal.

Yang harus Anda lakukan sekarang adalah memutuskan apakah semua AUTO Anda bergabung bertahan selama perubahan relationah agar sesuai dengan maksud pernyataan pilihan Anda.

1
JeffO