Dengan asumsi bahwa saya telah memahami skenario Anda dengan benar, inilah yang saya sebut sebagai cara yang benar untuk melakukan ini:
Mulailah dari deskripsi tingkat yang lebih tinggi dari database Anda! Anda memiliki karyawan, dan karyawan dapat menjadi karyawan "ce" dan karyawan "sn" (apa pun itu). Dalam istilah berorientasi objek, ada kelas "karyawan", dengan dua sub-kelas yang disebut "karyawan ce" dan "karyawan sn".
Maka Anda menerjemahkan ini deskripsi tingkat yang lebih tinggi untuk tiga tabel: employees
, employees_ce
dan employees_sn
:
employees(id, name)
employees_ce(id, ce-specific stuff)
employees_sn(id, sn-specific stuff)
Karena semua karyawan adalah karyawan (duh!), Setiap karyawan akan mendapat baris dalam employees
tabel. Karyawan "ce" juga memiliki baris di employees_ce
tabel, dan karyawan "sn" juga memiliki baris di employees_sn
tabel. employees_ce.id
adalah kunci asing employees.id
, sebagaimana employees_sn.id
adanya.
Untuk merujuk ke karyawan dalam bentuk apa pun (ce atau sn), lihat employees
tabel. Artinya, kunci asing yang bermasalah harus mengacu pada tabel itu!
Anda mungkin dapat menambahkan dua batasan kunci asing (sejujurnya: saya belum pernah mencobanya), tetapi kemudian bersikeras baris induk ada di kedua tabel.
Sebagai gantinya Anda mungkin ingin membuat supertipe untuk dua subtipe karyawan Anda, lalu arahkan kunci asing ke sana. (Dengan asumsi Anda memiliki alasan bagus untuk membagi dua jenis karyawan, tentunya).
type
di tabel karyawan akan menjadice
atausn
.sumber
LEFT JOIN
semuanya, jika jumlahnya cukup. Saat tidak menggunakan tabel dasar 'karyawan', kunci utama tidak dapat dideklarasikan (karena ini merujuk pada tableA atau tableB atau…); sekarang bisa. Kebijaksanaan membelahemployees_ce
danemployees_sn
diasumsikan, dan asumsi itu dicatat.Sebenarnya saya melakukan ini sendiri. Saya memiliki tabel bernama 'Komentar' yang berisi komentar untuk rekaman di 3 tabel lainnya. Tidak ada solusi yang benar-benar menangani semua yang mungkin Anda inginkan. Dalam kasus Anda, Anda akan melakukan ini:
Solusi 1:
Tambahkan bidang tinyint ke employee_ce dan employee_sn yang memiliki nilai default yang berbeda di setiap tabel (Bidang ini mewakili 'pengenal tabel', jadi kami akan menyebutnya tid_ce & tid_sn)
Buat Indeks Unik di setiap tabel menggunakan PK tabel dan bidang id tabel.
Tambahkan bidang tinyint ke tabel 'Pemotongan' Anda untuk menyimpan paruh kedua kunci asing (ID Tabel)
Buat 2 kunci asing di tabel 'Pemotongan' Anda (Anda tidak dapat menerapkan integritas referensial, karena salah satu kunci akan valid atau yang lainnya ... tetapi tidak pernah keduanya:
ALTER TABLE [dbo].[Deductions] WITH NOCHECK ADD CONSTRAINT [FK_Deductions_employees_ce] FOREIGN KEY([id], [fk_tid]) REFERENCES [dbo].[employees_ce] ([empid], [tid]) NOT FOR REPLICATION GO ALTER TABLE [dbo].[Deductions] NOCHECK CONSTRAINT [FK_600_WorkComments_employees_ce] GO ALTER TABLE [dbo].[Deductions] WITH NOCHECK ADD CONSTRAINT [FK_Deductions_employees_sn] FOREIGN KEY([id], [fk_tid]) REFERENCES [dbo].[employees_sn] ([empid], [tid]) NOT FOR REPLICATION GO ALTER TABLE [dbo].[Deductions] NOCHECK CONSTRAINT [FK_600_WorkComments_employees_sn] GO employees_ce -------------- empid name tid khce1 prince 1 employees_sn ---------------- empid name tid khsn1 princess 2 deductions ---------------------- id tid name khce1 1 gold khsn1 2 silver ** id + tid creates a unique index **
Solusi 2: Solusi ini memungkinkan integritas referensial dipertahankan: 1. Buat bidang kunci asing kedua di tabel 'Potongan', izinkan nilai Null di kedua kunci asing, dan buat kunci asing normal:
employees_ce -------------- empid name khce1 prince employees_sn ---------------- empid name khsn1 princess deductions ---------------------- idce idsn name khce1 *NULL* gold *NULL* khsn1 silver
Integritas hanya dicentang jika kolomnya bukan nol, sehingga Anda dapat mempertahankan integritas referensial.
sumber
Saya tahu ini adalah topik stagnan yang lama, tetapi jika ada yang mencari di sini adalah bagaimana saya menangani kunci asing multi tabel. Dengan teknik ini, Anda tidak memiliki operasi kaskade yang diberlakukan DBA, jadi pastikan Anda menangani
DELETE
dan semacamnya di kode Anda.Contoh SO Op akan terlihat seperti ini
deductions -------------- type id name 1 khce1 gold 2 khsn1 silver types --------------------- 1 employees_ce 2 employees_sn
sumber
Secara teknis mungkin. Anda mungkin akan mereferensikan employee_ce dalam potongan dan employee_sn. Tetapi mengapa Anda tidak menggabungkan employee_sn dan employee_ce? Saya tidak melihat alasan mengapa Anda memiliki dua meja. Tidak ada satu dengan banyak hubungan. Dan (tidak dalam contoh ini) banyak kolom.
Jika Anda melakukan dua referensi untuk satu kolom, seorang karyawan harus memiliki entri di kedua tabel.
sumber
Ya, itu mungkin. Anda perlu menentukan 2 FK untuk tabel ke-3. Setiap FK menunjuk ke field wajib dari satu tabel (yaitu 1 FK per tabel asing).
sumber
Dengan asumsi Anda harus memiliki dua tabel untuk dua jenis karyawan karena alasan tertentu, saya akan memperluas jawaban vmarquez:
Skema:
Data dalam potongan:
Ini akan memungkinkan Anda untuk memiliki poin deduksi ke tabel lain dalam skema Anda. Jenis hubungan ini tidak didukung oleh batasan tingkat database, IIRC jadi Anda harus memastikan Aplikasi Anda mengelola batasan dengan benar (yang membuatnya lebih rumit jika Anda memiliki beberapa Aplikasi / layanan berbeda yang menggunakan database yang sama).
sumber