Sejauh yang saya tahu, foreign key (FK) digunakan untuk membantu programmer memanipulasi data dengan cara yang benar. Misalkan seorang programmer benar-benar melakukan ini dengan cara yang benar, lalu apakah kita benar-benar membutuhkan konsep kunci asing?
Apakah ada kegunaan lain untuk kunci asing? Apakah saya melewatkan sesuatu di sini?
database
oracle
foreign-keys
Niyaz
sumber
sumber
Jawaban:
Kunci asing membantu menegakkan integritas referensial di tingkat data. Mereka juga meningkatkan kinerja karena biasanya diindeks secara default.
sumber
Kunci asing juga dapat membantu programmer menulis lebih sedikit kode menggunakan hal-hal seperti
ON DELETE CASCADE
. Ini berarti bahwa jika Anda memiliki satu tabel yang berisi pengguna dan tabel lainnya berisi pesanan atau sesuatu, maka menghapus pengguna secara otomatis dapat menghapus semua pesanan yang mengarah ke pengguna tersebut.sumber
Saya tidak bisa membayangkan mendesain database tanpa kunci asing. Tanpa mereka, pada akhirnya Anda pasti membuat kesalahan dan merusak integritas data Anda.
Sebenarnya mereka tidak diwajibkan , tetapi manfaatnya sangat besar.
Saya cukup yakin bahwa FogBugz tidak memiliki batasan kunci asing dalam database. Saya akan tertarik untuk mendengar bagaimana tim Fog Creek Software menyusun kode mereka untuk menjamin bahwa mereka tidak akan pernah menimbulkan inkonsistensi.
sumber
Skema database tanpa batasan FK seperti mengemudi tanpa sabuk pengaman.
Suatu hari, Anda akan menyesalinya. Tidak menghabiskan sedikit waktu ekstra untuk dasar-dasar desain dan integritas data adalah cara yang pasti untuk memastikan sakit kepala nanti.
Apakah Anda menerima kode dalam aplikasi Anda yang ceroboh itu? Itu secara langsung mengakses objek anggota dan memodifikasi struktur datanya secara langsung.
Menurut Anda mengapa hal ini menjadi sulit dan bahkan tidak dapat diterima dalam bahasa modern?
sumber
Iya.
ON DELETE CASCADE
sumber
Membuat anggapan seperti itu bagi saya merupakan ide yang sangat buruk; Secara umum, perangkat lunak sangat buggy.
Dan itulah intinya, sungguh. Pengembang tidak bisa melakukan semuanya dengan benar, jadi memastikan database tidak dapat diisi dengan data yang buruk adalah Hal yang Baik.
Meskipun dalam dunia yang ideal, gabungan natural akan menggunakan hubungan (yaitu batasan FK) daripada mencocokkan nama kolom. Ini akan membuat FK lebih berguna.
sumber
Secara pribadi, saya lebih menyukai kunci asing karena ini memformalkan hubungan antara tabel. Saya menyadari bahwa pertanyaan Anda mengandaikan bahwa pemrogram tidak memperkenalkan data yang akan melanggar integritas referensial, tetapi saya telah melihat terlalu banyak contoh di mana integritas referensial data dilanggar, meskipun ada niat terbaik!
Batasan kunci pra-asing (alias integritas referensial deklaratif atau DRI) banyak waktu dihabiskan untuk mengimplementasikan hubungan ini menggunakan pemicu. Fakta bahwa kita dapat memformalkan hubungan dengan batasan deklaratif sangatlah kuat.
@ John - Database lain dapat secara otomatis membuat indeks untuk kunci asing, tetapi SQL Server tidak. Di SQL Server, hubungan kunci asing hanyalah batasan. Anda harus menentukan indeks Anda pada kunci asing secara terpisah (yang dapat bermanfaat.)
Sunting: Saya ingin menambahkan bahwa, IMO, penggunaan kunci asing untuk mendukung ON DELETE atau ON UPDATE CASCADE tidak selalu merupakan hal yang baik. Dalam praktiknya, saya telah menemukan bahwa kaskade saat menghapus harus dipertimbangkan dengan cermat berdasarkan hubungan data - misalnya, apakah Anda memiliki orang tua-anak alami di mana ini mungkin OK atau tabel terkait sekumpulan nilai pencarian. Menggunakan pembaruan berjenjang menyiratkan Anda mengizinkan kunci utama dari satu tabel untuk dimodifikasi. Dalam hal ini, saya memiliki ketidaksepakatan filosofis umum bahwa kunci utama tabel tidak boleh berubah. Kunci harus konstan secara inheren.
sumber
Tanpa kunci asing, bagaimana Anda mengetahui bahwa dua rekaman dalam tabel yang berbeda terkait?
Menurut saya yang Anda maksud adalah integritas referensial, di mana rekaman turunan tidak boleh dibuat tanpa rekaman induk yang ada, dll. Ini sering kali dikenal sebagai batasan kunci asing - tetapi jangan disamakan dengan keberadaan kunci asing di posisi pertama.
sumber
Apakah ada manfaatnya tidak memiliki kunci asing? Kecuali Anda menggunakan database yang jelek, FK tidak terlalu sulit untuk diatur. Jadi mengapa Anda memiliki kebijakan untuk menghindarinya? Memiliki konvensi penamaan yang mengatakan kolom mereferensikan hal lain adalah satu hal, mengetahui database sebenarnya memverifikasi hubungan itu untuk Anda adalah hal lain.
sumber
Saya kira Anda berbicara tentang batasan kunci asing yang diberlakukan oleh database . Anda mungkin sudah menggunakan kunci asing, Anda belum memberi tahu database tentangnya.
Secara teoritis, tidak. Namun, tidak pernah ada perangkat lunak tanpa bug.
Bug dalam kode aplikasi biasanya tidak terlalu berbahaya - Anda mengidentifikasi bug dan memperbaikinya, dan setelah itu aplikasi berjalan kembali dengan lancar. Tetapi jika bug memungkinkan data Currupt masuk ke database, maka Anda terjebak dengannya! Sangat sulit untuk memulihkan dari data yang rusak dalam database.
Pertimbangkan jika bug halus di FogBugz mengizinkan kunci asing yang rusak untuk ditulis di database. Mungkin mudah untuk memperbaiki bug dan dengan cepat memberikan perbaikan kepada pelanggan dalam rilis perbaikan bug. Namun, bagaimana cara memperbaiki data yang korup di lusinan database? Kode yang benar sekarang mungkin tiba-tiba rusak karena asumsi tentang integritas kunci asing tidak berlaku lagi.
Dalam aplikasi web Anda biasanya hanya memiliki satu program yang berbicara ke database, jadi hanya ada satu tempat di mana bug dapat merusak data. Dalam aplikasi perusahaan mungkin ada beberapa aplikasi independen yang berbicara ke database yang sama (belum lagi orang yang bekerja langsung dengan shell database). Tidak ada cara untuk memastikan bahwa semua aplikasi mengikuti asumsi yang sama tanpa bug, selalu dan selamanya.
Jika batasan dikodekan dalam database, maka hal terburuk yang dapat terjadi dengan bug adalah bahwa pengguna diperlihatkan pesan kesalahan jelek tentang beberapa batasan SQL tidak puas. Ini lebih disukai daripada membiarkan data saat ini masuk ke dalam database perusahaan Anda, yang pada gilirannya akan merusak semua aplikasi Anda atau hanya menyebabkan semua jenis keluaran yang salah atau menyesatkan.
Oh, dan batasan kunci asing juga meningkatkan kinerja karena diindeks secara default. Saya tidak dapat memikirkan alasan apa pun untuk tidak menggunakan batasan kunci asing.
sumber
FK sangat penting dan harus selalu ada dalam skema Anda, kecuali Anda eBay .
sumber
unibrow
Saya pikir beberapa hal di beberapa titik harus bertanggung jawab untuk memastikan hubungan yang valid.
Misalnya, Ruby on Rails tidak menggunakan kunci asing, tetapi memvalidasi semua hubungan itu sendiri. Jika Anda hanya pernah mengakses database Anda dari aplikasi Ruby on Rails, ini bagus.
Namun, jika Anda memiliki klien lain yang menulis ke database, maka tanpa kunci asing mereka perlu mengimplementasikan validasinya sendiri. Anda kemudian memiliki dua salinan dari kode validasi yang kemungkinan besar berbeda, yang harus diketahui oleh setiap programmer adalah dosa utama.
Pada titik itu, kunci asing benar-benar diperlukan, karena memungkinkan Anda untuk memindahkan tanggung jawab ke satu titik lagi.
sumber
Kunci asing memungkinkan seseorang yang belum pernah melihat database Anda sebelumnya untuk menentukan hubungan antar tabel.
Semuanya mungkin baik-baik saja sekarang, tetapi pikirkan apa yang akan terjadi ketika programmer Anda pergi dan orang lain harus mengambil alih.
Kunci asing akan memungkinkan mereka untuk memahami struktur database tanpa menelusuri ribuan baris kode.
sumber
FK memungkinkan DBA untuk melindungi integritas data dari pengguna yang meraba-raba ketika programmer gagal melakukannya, dan terkadang untuk melindungi dari programmer yang meraba-raba.
Programmer fana dan bisa salah. FK bersifat deklaratif yang membuat mereka lebih sulit untuk dikacaukan.
Meskipun ini bukan alasan mengapa mereka dibuat, FK memberikan petunjuk andal yang kuat untuk alat pembuatan diagram dan untuk membuat kueri. Ini diteruskan ke pengguna akhir, yang sangat membutuhkan petunjuk kuat yang dapat diandalkan.
sumber
Mereka tidak benar-benar diperlukan, karena sabuk pengaman tidak sepenuhnya diperlukan. Tetapi mereka benar-benar dapat menyelamatkan Anda dari melakukan sesuatu yang bodoh yang mengacaukan database Anda.
Jauh lebih baik untuk men-debug kesalahan kendala FK daripada harus merekonstruksi penghapusan yang merusak aplikasi Anda.
sumber
Mereka penting, karena aplikasi Anda bukan satu-satunya cara untuk memanipulasi data dalam database. Aplikasi Anda dapat menangani integritas referensial sejujur yang diinginkannya, tetapi yang diperlukan hanyalah satu bozo dengan hak istimewa yang tepat untuk ikut serta dan mengeluarkan perintah penyisipan, penghapusan, atau pembaruan di tingkat database, dan semua penegakan integritas referensial aplikasi Anda dilewati. Menempatkan batasan FK di tingkat database berarti, jika bozo ini tidak memilih untuk menonaktifkan batasan FK sebelum mengeluarkan perintahnya, batasan FK akan menyebabkan pernyataan insert / update / delete yang buruk gagal dengan pelanggaran integritas referensial.
sumber
Saya memikirkannya dalam hal biaya / manfaat ... Di MySQL , menambahkan batasan adalah satu baris tambahan DDL . Itu hanya beberapa kata kunci dan beberapa detik pemikiran. Itulah satu-satunya "biaya" menurut saya ...
Alat menyukai kunci asing. Kunci asing mencegah data buruk (yaitu, baris yatim piatu) yang mungkin tidak memengaruhi logika atau fungsionalitas bisnis dan karenanya tidak diketahui, dan menumpuk. Ini juga mencegah pengembang yang tidak terbiasa dengan skema untuk mengimplementasikan seluruh bagian pekerjaan tanpa menyadari bahwa mereka kehilangan suatu hubungan. Mungkin semuanya bagus dalam lingkup aplikasi Anda saat ini, tetapi jika Anda melewatkan sesuatu dan suatu hari sesuatu yang tidak terduga ditambahkan (pikirkan pelaporan mewah), Anda mungkin berada di tempat di mana Anda harus secara manual membersihkan data buruk yang telah terakumulasi sejak awal. skema tanpa pemeriksaan yang diberlakukan database.
Sedikit waktu yang diperlukan untuk menyusun apa yang sudah ada di kepala Anda ketika Anda menyusun sesuatu dapat menyelamatkan Anda atau orang lain dari sekumpulan kesedihan berbulan-bulan atau bertahun-tahun yang akan datang.
Pertanyaan:
Ini sedikit dimuat. Sisipkan komentar, indentasi, atau penamaan variabel sebagai ganti "kunci asing" ... Jika Anda sudah memahami hal yang dimaksud dengan sempurna, "tidak ada gunanya" bagi Anda.
sumber
Pengurangan entropi. Mengurangi potensi skenario kacau terjadi di database. Kami mengalami kesulitan karena mempertimbangkan semua kemungkinan sehingga, menurut pendapat saya, pengurangan entropi adalah kunci pemeliharaan sistem apa pun.
Ketika kita membuat asumsi misalnya: setiap pesanan memiliki pelanggan asumsi itu harus dipaksakan oleh sesuatu . Dalam database bahwa "sesuatu" adalah kunci asing.
Saya pikir ini sepadan dengan pengorbanan dalam kecepatan pengembangan. Tentu, Anda dapat membuat kode lebih cepat dengan menonaktifkannya dan mungkin inilah mengapa beberapa orang tidak menggunakannya. Secara pribadi saya telah menghabiskan beberapa jam dengan NHibernate dan beberapa kendala kunci asing yang membuat marah ketika saya melakukan beberapa operasi. NAMUN, saya tahu apa masalahnya jadi itu bukan masalah. Saya menggunakan alat biasa dan ada sumber daya untuk membantu saya mengatasi hal ini, bahkan mungkin orang yang dapat membantu!
Alternatifnya adalah mengizinkan bug menyusup ke dalam sistem (dan diberikan waktu yang cukup, itu akan terjadi) di mana kunci asing tidak disetel dan data Anda menjadi tidak konsisten. Kemudian, Anda mendapatkan laporan bug yang tidak biasa, selidiki dan "OH". Basis data kacau. Sekarang berapa lama waktu yang dibutuhkan untuk memperbaikinya?
sumber
Anda dapat melihat kunci asing sebagai pembatas yang,
sumber
Saat ini kami tidak menggunakan kunci asing. Dan sebagian besar kami tidak menyesalinya.
Karena itu - kami cenderung mulai menggunakannya lebih banyak dalam waktu dekat karena beberapa alasan, keduanya karena alasan yang sama:
Pembuatan diagram. Jauh lebih mudah untuk membuat diagram database jika ada hubungan kunci asing yang digunakan dengan benar.
Alat pendukung. Jauh lebih mudah untuk membangun model data menggunakan Visual Studio 2008 yang dapat digunakan untuk LINQ ke SQL jika ada hubungan kunci asing yang tepat.
Jadi saya rasa maksud saya adalah bahwa kami telah menemukan bahwa jika kami melakukan banyak pekerjaan SQL manual (membuat kueri, menjalankan kueri, bla bla bla)) kunci asing tidak selalu penting. Namun, begitu Anda mulai menggunakan alat, alat menjadi jauh lebih berguna.
sumber
Hal terbaik tentang batasan kunci asing (dan batasan secara umum, sebenarnya) adalah Anda dapat mengandalkannya saat menulis kueri Anda. Banyak kueri bisa menjadi jauh lebih rumit jika Anda tidak dapat mengandalkan model data yang memiliki "true".
Dalam kode, biasanya kita hanya akan mendapatkan pengecualian yang dilemparkan ke suatu tempat - tetapi dalam SQL , biasanya kita hanya akan mendapatkan jawaban yang "salah".
Secara teori, SQL Server dapat menggunakan batasan sebagai bagian dari rencana kueri - tetapi kecuali untuk kendala pemeriksaan untuk partisi, saya tidak dapat mengatakan bahwa saya pernah benar-benar menyaksikannya.
sumber
Kunci asing tidak pernah eksplisit (tabel REFERENSI KUNCI ASING (kolom)) dinyatakan dalam proyek (aplikasi bisnis dan situs jejaring sosial) yang saya kerjakan.
Tapi selalu ada semacam konvensi penamaan kolom yang merupakan kunci asing.
Ini seperti normalisasi database - Anda harus tahu apa yang Anda lakukan dan apa konsekuensi dari itu (terutama kinerja).
Saya mengetahui keuntungan dari kunci asing (integritas data, indeks untuk kolom kunci asing, alat yang mengetahui skema database), tetapi juga saya takut menggunakan kunci asing sebagai aturan umum.
Juga berbagai mesin database dapat melayani kunci asing dengan cara yang berbeda, yang dapat menyebabkan bug halus selama migrasi.
Menghapus semua pesanan dan faktur klien yang dihapus dengan ON DELETE CASCADE adalah contoh sempurna dari skema database yang terlihat bagus, tetapi salah desain.
sumber
Iya. ON DELETE [RESTRICT | CASCADE] mencegah pengembang dari data terdampar, menjaga data tetap bersih. Saya baru-baru ini bergabung dengan tim pengembang Rails yang tidak fokus pada batasan database seperti kunci asing.
Untungnya, saya menemukan ini: http://www.redhillonrails.org/foreign_key_associations.html - RedHill on Ruby on Rails plug-in menghasilkan kunci asing menggunakan konvensi atas gaya konfigurasi . Migrasi dengan product_id akan membuat kunci asing ke id di tabel produk .
Lihat plugin hebat lainnya di RedHill , termasuk migrasi yang dibungkus dalam transaksi.
sumber
Jika Anda berencana membuat kode akses data Anda, yaitu, Entity Framework atau ORM lainnya, Anda sepenuhnya kehilangan kemampuan untuk membuat model hierarki tanpa Foreign Key
sumber