Pada struktur database saya di SQL Server, saya memiliki 3 jenis produk yang memerlukan informasi berbeda tentang pesanan. Jadi, saya membuat satu Customers
meja dan tiga perintah tabel yang berbeda: OrdersForProductAs
, OrdersForProductBs
, OrdersForProductCs
. Semua tabel pesanan memiliki satu hingga banyak hubungan di atas Customers
meja.
Saya juga punya meja lain yaitu Payments
dan akan menyimpan rincian pembayaran di dalamnya. Tapi saya ragu di sini tentang cara menyusunnya.
Karena saya memiliki beberapa jenis produk dan pelanggan mungkin memiliki pesanan untuk beberapa produk secara bersamaan, saya perlu menghubungkan ketiga tabel pesanan ke Payments
tabel.
Masalah lainnya adalah bahwa pelanggan mungkin memiliki pesanan hanya untuk satu jenis produk. Jadi, kolom FK pada Payments
tabel perlu nullable
.
Pertanyaan saya adalah apakah nullable
kolom-kolom FK itu akan menjadi sakit kepala bagi saya dalam jangka panjang atau tidak? Secara umum, akankah dianggap sebagai praktik yang buruk untuk memiliki kolom FK yang dapat dibatalkan pada tabel?
Jawaban:
Saya akan mempertanyakan mengapa Anda memiliki
OrdersForProductX
tabel sama sekali.Mungkin masalah FK yang Anda tanyakan dapat dirancang ...
Jika tabel ini memiliki struktur yang sama, maka Anda hanya perlu
ProductType
kolom pada beberapaOrderProduct
tabel. KemudianPayment
hanya tautan ke sana dengan satu FKJika tabel memiliki struktur yang berbeda, saya berasumsi mereka memiliki beberapa atribut yang sama. Jadi, Anda dapat memiliki
OrderProduct
tabel umum kemudian tabel anak spesifik per jenis produk (lihat di bawah) Sekali lagi,Payment
tautkan ke tabel commone dengan satu FKIni adalah "pola superkey / subtipe"
(OrderID, ProductType)
Memesan produk
PesanProdukA
PesanProdukB
sumber
NULL
kolom FK dengan pendekatan ini.Hindari "kunci asing" yang tidak dapat dibatalkan. Mereka memiliki banyak kelemahan.
Batasan pada baris referensi tidak selalu ditegakkan ketika kunci asing berisi nol. Namun, perilaku default itu tidak konsisten antara DBMS yang berbeda. Beberapa DBMS mendukung opsi konfigurasi untuk mengubah perilaku kunci asing yang dapat dibatalkan dan beberapa tidak. Oleh karena itu, pengembang dan pengguna SQL mungkin tidak jelas tentang apa arti batasan kunci asing yang dapat dibatalkan dari perspektif integritas data. Porting database antara produk DBMS atau bahkan antara server yang berbeda menggunakan produk yang sama dapat memberikan hasil yang tidak konsisten.
Alat desain basis data, alat integrasi, dan perangkat lunak lain tidak selalu mendukungnya dengan benar dan hasil yang mereka hasilkan mungkin salah.
Kunci asing sering digunakan dalam gabungan dan logika kueri lainnya, memperparah masalah bagi pengguna yang berpikir kendala berlaku ketika tidak atau yang tidak tahu logika yang diterapkan oleh DBMS khusus Anda.
Beberapa fitur pengoptimalan kueri yang memungkinkan penulisan ulang kueri dan pengoptimalan lainnya mungkin tidak tersedia ketika kunci asing dibatalkan.
Dalam istilah logis, batasan "kunci asing" yang tidak dapat dibatalkan tidak masuk akal secara logis. Menurut standar SQL kendala seperti itu mungkin tidak dilanggar bahkan jika tabel yang direferensikan kosong. Itu bertentangan dengan salah satu justifikasi dugaan paling umum untuk menggunakan null - yang mewakili kasus "tidak diketahui". Jika tidak ada nilai X yang valid maka X "tidak dikenal" pasti tidak bisa menjadi nilai yang valid - dan SQL akan mengizinkannya.
Kunci asing yang dapat dibatalkan tidak perlu sama sekali. Anda selalu bisa menguraikan kunci asing ke tabel baru atau menggunakan pola supertipe / subtipe sehingga nol tidak diperlukan. Demi kesederhanaan dan akurasi, lebih baik meninggalkan nol daripada memasukkannya.
sumber
Saya belum pernah mendengar itu dianggap praktik buruk untuk menggunakan kolom FK yang dapat dibatalkan. Mereka sangat cocok untuk kolom yang mereferensikan tabel lain tetapi mungkin tidak diisi (yaitu data opsional).
(Mengapa menurut Anda itu akan menjadi masalah?)
sumber