Apakah dapat diterima untuk memiliki referensi melingkar antara dua tabel di bidang kunci asing?
Jika tidak, bagaimana situasi ini dapat dihindari?
Jika demikian, bagaimana cara memasukkan data?
Di bawah ini adalah contoh di mana (menurut saya) referensi melingkar dapat diterima:
CREATE TABLE Account
(
ID INT PRIMARY KEY IDENTITY,
Name VARCHAR(50)
)
CREATE TABLE Contact
(
ID INT PRIMARY KEY IDENTITY,
Name VARCHAR(50),
AccountID INT FOREIGN KEY REFERENCES Account(ID)
)
ALTER TABLE Account ADD PrimaryContactID INT FOREIGN KEY REFERENCES Contact(ID)
database-design
foreign-key
rdbms
KidCode
sumber
sumber
Jawaban:
Karena Anda menggunakan bidang yang dapat dibatalkan untuk kunci asing, Anda sebenarnya dapat membangun sistem yang berfungsi dengan benar seperti yang Anda bayangkan. Untuk memasukkan baris ke dalam tabel Akun, Anda harus memiliki baris yang ada di tabel Kontak kecuali Anda mengizinkan sisipan ke dalam Akun dengan null PrimaryContactID. Untuk membuat baris kontak tanpa harus memiliki baris Akun, Anda harus membiarkan kolom AccountID di tabel Kontak menjadi nullable. Ini memungkinkan Akun tidak memiliki kontak, dan memungkinkan Kontak tidak memiliki akun. Mungkin ini diinginkan, mungkin tidak.
Karena itu, preferensi pribadi saya adalah memiliki pengaturan berikut:
Ini memberikan kemampuan untuk:
IX_AccountsContactsXRef_Primary
indeks. Indeks ini berisi filter, sehingga hanya akan berfungsi pada platform yang mendukungnya. Karena indeks ini ditentukan denganUNIQUE
opsi, hanya ada satu kontak utama untuk setiap akun.Misalnya, jika Anda ingin menampilkan daftar semua kontak, dengan kolom yang menunjukkan status "primer", menampilkan kontak utama di bagian atas daftar untuk setiap Akun, Anda dapat melakukan:
Indeks yang difilter mencegah penyisipan lebih dari satu kontak utama per akun, sementara secara bersamaan memberikan metode cepat untuk mengembalikan daftar kontak utama. Seseorang dapat dengan mudah membayangkan kolom lain,
IsActive
dengan indeks yang disaring tidak unik untuk mempertahankan riwayat kontak per akun, bahkan setelah kontak itu tidak lagi dikaitkan dengan akun:sumber
Tidak, tidak dapat diterima untuk memiliki referensi kunci asing melingkar. Bukan hanya karena tidak mungkin memasukkan data tanpa terus-menerus menjatuhkan dan menciptakan kembali kendala. tetapi karena itu adalah model cacat mendasar dari setiap dan setiap domain yang dapat saya pikirkan. Dalam contoh Anda, saya tidak dapat memikirkan domain mana pun di mana hubungan antara Akun dan Kontak bukan NN, membutuhkan tabel persimpangan dengan referensi FK kembali ke Akun dan Kontak.
sumber
Anda dapat mengarahkan objek eksternal ke kontak utama, bukan ke akun. Data Anda akan terlihat seperti ini:
sumber