Sejauh yang saya bisa temukan banyak DBMS (misalnya mysql, postgres, mssql) menggunakan kombinasi fk dan pk hanya untuk membatasi perubahan pada data, tetapi jarang digunakan untuk secara otomatis memilih kolom untuk bergabung (seperti natural join dengan nama). Mengapa demikian? Jika Anda sudah mendefinisikan hubungan antara 2 tabel dengan pk / fk, mengapa database 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.
sumber
NATURAL JOIN
(itulah sebabnya saya biasanya menghindarinya), tetapi saya tidak berpikir bahwa itu sendiri seharusnya berarti bahwa dbms tidak dapat mengimplementasikan cara otomatis untuk bergabung dengan tabel berdasarkan kunci asing.AUTO JOIN mytable THROUGH myrelation
, itu akan sangat menyenangkan.InnerJoin(SRC_TABLE.rDEST_TABLE.REL_NAME_F01)
Kunci asing dimaksudkan untuk membatasi data. yaitu menegakkan integritas referensial. Itu dia. Tidak ada lagi.
Anda dapat memiliki beberapa kunci asing ke tabel yang sama. Pertimbangkan hal berikut di mana pengiriman memiliki titik awal, dan titik akhir.
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.
Anda akan sering melewati 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.
Dalam beberapa kasus khusus, Anda akan bergabung di kolom yang tidak unik. Karenanya kehadiran PK / FK di kolom-kolom itu tidak mungkin.
Anda mungkin berpikir poin 2 dan 3 di atas tidak relevan karena pertanyaan Anda adalah kapan ada IS satu hubungan PK / FK antara 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.
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 menggabungkan "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 tabel bergabung. 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.
sumber
SQL dan Teori Relasional: Cara Menulis Kode SQL yang Akurat Menurut Tanggal CJ
SQL standar sudah memiliki fitur seperti itu, yang dikenal sebagai
NATURAL JOIN
, dan telah diimplementasikan 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: ketika menulisINNER JOIN
InteliSense menyarankanON
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.sumber
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. IE untuk satu set data dan kueri yang diberikan 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 menjaga properti SQL yang "dapat dibuktikan secara matematis".
Jika Anda mengizinkan basis data 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.
sumber
Meskipun Anda telah menetapkan hubungan Foreign Key, itu tidak berarti bahwa 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.
sumber
Anda mungkin beroperasi dengan asumsi yang salah. Anda mengatakan 'sejauh yang Anda bisa tahu' tetapi tidak memberikan bukti empiris atau bukti. Jika pk atau fk adalah indeks terbaik untuk kueri, itu akan digunakan. Saya tidak tahu mengapa Anda melihat ini, tapi dugaan saya kurang bagus.
Edit sekarang bahwa pertanyaannya telah ditulis ulang sepenuhnya: Kasus yang Anda uraikan hanya akan untuk satu set 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.
sumber
Ada banyak alasan mengapa database tidak dapat melakukan ini dengan aman, termasuk fakta bahwa menambah / menghapus Kunci Asing akan mengubah arti dari permintaan pra-tertulis termasuk permintaan 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 nilai 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 alat desain kueri atau editor teks tidak dapat secara otomatis menyelesaikan bergabung dengan bantuan Foreign Keys dengan cara yang sama seperti mereka memberi Anda intellisense pada nama kolom. Anda dapat mengedit kueri jika alat itu 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 ia memulai studio manajemen!)
sumber
Alami bergabung dengan "secara otomatis" bergabung pada persamaan kolom umum, tetapi Anda hanya boleh menulis bahwa jika itu yang Anda inginkan berdasarkan 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 "secara otomatis" bergabung per 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 agar tidak menggunakan batasan yang dinyatakan baru.sudah meninggalkan artinya 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 tentang 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?
sumber
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 kebetulan merupakan fitur bagus 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;
sintaksis yang tidak menyertakan cara untuk menentukan kolom mana yang akan digunakan. Baik mengandalkan hubungan antara tabel, yang membuat mereka tidak dapat diandalkan (sintaks bergabung alami lebih dari ekstensi).Tidak ada kendala mendasar untuk "tabel gabung dalam pada 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-orang yang merancang bahasa tersebut menganggap bahwa a) ide yang bagus dan b) lebih baik untuk dikerjakan daripada beberapa perubahan bahasa lainnya ...
sumber
Jika menghilangkan klausa ON diasumsikan mengikuti bidang berdasarkan integritas referensial, bagaimana Anda akan melakukan produk Cartesian?
Sunting: menggunakan AUTO Kelebihan dari ini adalah sedikit mengetik dan Anda tidak perlu tahu bagaimana mereka bergabung atau ingat bergabung dengan 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 relasi untuk mencocokkan maksud pernyataan pilihan Anda.
sumber
Sebagian alasannya adalah:
1 - secara teori Anda dapat bergabung dengan tabel pada kolom acak dari dua tabel. Meskipun ini bukan praktik umum, itu valid. Ingat bahwa SQL seperti bahasa pemrograman, ia tidak mengerti informasi apa yang ada di dalam kolom tentu saja dan nama, untuk SQL, tidak banyak berarti dalam hal ini.
2 - Ada berbagai jenis sambungan (kiri, kanan, dalam) - Bergabung dalam hanya 1 dari mereka.
3 - Standar SQL dapat dipandu oleh prinsip menjadi bahasa tingkat rendah yang memungkinkan dialek tingkat tinggi untuk membentuk kecerdasan menggunakannya. Perbandingannya agak lebih jelas jika Anda memikirkan bahasa generasi ke-4 vs bahasa generasi ke-3. Bahkan, satu alat yang saya gunakan, IEF, memungkinkan Anda untuk menulis sesuatu seperti ini:
Ringkasnya, saran Anda menarik dan dapat diimplementasikan baik sebagai bagian dari standar atau sebagai prosedur tersimpan (standarnya adalah Inner Join).
sumber
Tiddo, saya yakin Anda sepenuhnya benar, SQL tentang topik itu cukup bodoh , dan saya ingat pernah memikirkan hal yang sama dengan Anda mengenai kunci asing saat mempelajari SQL sekitar sepuluh tahun yang lalu.
Ok, mengingat itu, saya akhirnya harus lulus ujian itu; dan untuk melewatinya, saya harus melepaskannya . SQL lebih merupakan sebuah trainwreck daripada siapa pun mungkin mengakui, jalur standardisasi adalah bencana yang lengkap, dan beberapa implementasi mengancam untuk menyelesaikan lengkap . Masih cukup berguna, secara umum. (Aku bukan luddite K / V)
Kunci asing, lalu ... tidak berguna sama sekali. Mereka adalah konsep penting dalam model relasional , ok, tetapi fitur SQL dengan nama yang sama tidak dapat dibandingkan dengan baik.
Katakan langsung: jangan gunakan fitur SQL yang disebut
Foreign Key
sama sekali , sampai Anda menekan beberapa sistem besar dengan masalah kinerja. Eksplisit mengatakan mesin yang bidang adalah kunci asing dan yang tidak adalah hanya digunakan untuk mengindeks, dan itu terlihat oleh pengguna db.Apakah itu menyesatkan?
Iya.
Apakah mereka akan menjadikannya lebih kuat sekarang, setelah 30 tahun orang menyesatkan?
Tidak mungkin.
Mengabaikan Kunci Asing sepenuhnya sampai diperlukan ... memperbaiki SQL untuk saya?
Iya!
Dan mengapa sih semua ini terjadi?
Nah, fitur yang kita sebut kunci asing ditambahkan kemudian, ke SQL; SQL adalah standar yang berkembang seiring waktu, dari bawah ke atas. Vendor menerapkan fitur menggelikan, sementara badan standar facepalmed.
Kunci asing seperti yang dikatakan, di mana hanya dimaksudkan untuk pengindeksan dan tidak ada konstruk GABUNG yang tersedia. (Bergabung ketika dilakukan dengan
SELECT
queries,JOIN
queries cukup baru dan hanya dimaksudkan untukSELECT
fungsionalitas) Mereka mungkin berpikir bahwa memanggil bendera pengindeksanFOREIGN KEY
, adalah hacking penamaan cerdas atas konsep teori db relasional.sumber