Saya harus memodelkan situasi di mana saya memiliki tabel Chequing_Account (yang berisi anggaran, nomor iban, dan detail akun lainnya) yang harus dikaitkan dengan dua tabel yang berbeda, Person dan Corporation yang keduanya dapat memiliki 0, 1 atau banyak akun chequing.
Dengan kata lain saya memiliki dua hubungan 1-ke-banyak dengan akun Chequing tabel yang sama
Saya ingin mendengar solusi untuk masalah ini yang menghormati persyaratan normalisasi. Sebagian besar solusi yang saya dengar adalah:
1) menemukan entitas yang sama yang dimiliki oleh Person dan Corporation dan membuat tabel tautan antara ini dan tabel Chequing_Account, ini tidak mungkin dalam kasus saya dan bahkan jika saya ingin menyelesaikan masalah umum dan bukan contoh khusus ini.
2) Buat dua tabel tautan PersonToChequingAccount dan CorporationToChequingAccount yang menghubungkan kedua entitas dengan Akun Chequing. Namun saya tidak ingin dua Orang memiliki akun pemalsuan yang sama, dan saya tidak ingin orang biasa dan Perusahaan berbagi akun pemalsuan! lihat gambar ini
3) Buat dua kunci asing di Akun Chequing yang mengarah ke Korporasi dan Orang Alami, namun saya akan menegaskan bahwa Seseorang dan Perusahaan dapat memiliki banyak akun chequing, namun saya harus memastikan secara manual bahwa untuk setiap baris ChequingAccount tidak semua hubungan menunjuk ke Korporasi dan orang Alami karena akun checquing adalah dari korporasi atau Orang Alami. lihat gambar ini
Apakah ada solusi pembersih lain untuk masalah ini?
sumber
OwnerTypeID
diChecquingAccount
meja, dengan1=Corporation
dan2=NaturalPerson
? Dengan begitu Anda hanya perlu satuOwnerID
diChecquingAccount
tabel, yang dapat Anda indeks bersama denganOwnerTypeID
.CHECK (CorporationID IS NOT NULL AND NaturalPersonID IS NULL OR CorporationID IS NULL AND NaturalPersonID IS NOT NULL)
Saya lebih suka solusi 1 (tapi itu hanya saya). Jauh lebih "bersih".ChecquingAccount
catatan di dalam tabelOwnerTypeID=1
danOwnerID=123
, menunjukkan bahwa itu adalah tipeCorporation
, oleh karena itu ID123
di dalamCorporation
tabel. OwnerTypeID memberi tahu Anda tabel mana, dan OwnerID memberi tahu Anda ID di tabel itu.Customers
meja.Jawaban:
Database relasional tidak dibangun untuk menangani situasi ini dengan sempurna. Anda harus memutuskan apa yang paling penting bagi Anda dan kemudian membuat trade-off Anda. Anda memiliki beberapa tujuan:
Masalahnya adalah bahwa beberapa tujuan ini saling bersaing.
Solusi Sub-Pengetikan
Anda dapat memilih solusi sub-pengetikan tempat Anda membuat tipe-super yang menggabungkan korporasi dan orang. Super-type ini mungkin akan memiliki kunci majemuk dari kunci alami dari sub-tipe plus atribut partisi (misalnya
customer_type
). Ini bagus sejauh normalisasi berjalan dan memungkinkan Anda untuk menegakkan integritas referensial serta kendala bahwa perusahaan dan orang-orang saling eksklusif. Masalahnya adalah hal ini membuat pengambilan data lebih sulit, karena Anda selalu harus melakukan percabangan berdasarkancustomer_type
saat Anda bergabung dengan akun ke pemegang akun. Ini mungkin berarti menggunakanUNION
dan memiliki banyak SQL berulang dalam permintaan Anda.Solusi Dua Kunci Asing
Anda bisa memilih solusi di mana Anda menyimpan dua kunci asing di tabel akun Anda, satu untuk perusahaan dan satu untuk orang. Solusi ini juga memungkinkan Anda untuk mempertahankan integritas referensial, normalisasi, dan eksklusivitas bersama. Ini juga memiliki kelemahan pengambilan data yang sama dengan solusi sub-mengetik. Sebenarnya, solusi ini sama seperti solusi sub-pengetikan kecuali bahwa Anda mendapatkan masalah percabangan logika bergabung Anda "lebih cepat".
Namun demikian, banyak pemodel data akan menganggap solusi ini lebih rendah daripada solusi sub-pengetikan karena cara kendala saling eksklusivitas diberlakukan. Dalam solusi pengetikan Anda menggunakan kunci untuk menegakkan eksklusivitas timbal balik. Dalam dua solusi kunci asing Anda menggunakan
CHECK
batasan. Saya kenal beberapa orang yang memiliki bias yang tidak dapat dibenarkan terhadap kendala pemeriksaan. Orang-orang ini akan lebih suka solusi yang menjaga kendala dalam kunci.Solusi Atribut Pemisahan yang "Dinormalisasi"
Ada opsi lain di mana Anda menyimpan satu kolom kunci asing di tabel akun yang menarik dan menggunakan kolom lain untuk memberi tahu Anda bagaimana menafsirkan kolom kunci asing (RoKa
OwnerTypeID
kolom). Ini pada dasarnya menghilangkan tabel super-type dalam solusi sub-mengetik dengan mendenormalkan atribut partisi ke tabel anak. (Perhatikan bahwa ini tidak sepenuhnya "denormalisasi" sesuai dengan definisi formal, karena atribut partisi adalah bagian dari kunci utama.) Solusi ini tampaknya cukup sederhana karena ia tidak memiliki tabel tambahan untuk melakukan lebih kurang hal yang sama dan itu memotong jumlah kolom kunci asing menjadi satu. Masalah dengan solusi ini adalah bahwa itu tidak menghindari percabangan logika pengambilan dan terlebih lagi, itu tidak memungkinkan Anda untuk mempertahankan integritas referensial deklaratif . Database SQL tidak memiliki kemampuan untuk mengelola kolom kunci asing tunggal untuk salah satu dari beberapa tabel induk.Shared Domain Key Solution Utama
Salah satu cara orang kadang-kadang berurusan dengan masalah ini adalah dengan menggunakan kumpulan ID tunggal sehingga tidak ada kebingungan untuk ID yang diberikan apakah itu milik satu sub-jenis atau lainnya. Ini mungkin akan bekerja secara alami dalam skenario perbankan, karena Anda tidak akan mengeluarkan nomor rekening bank yang sama untuk perusahaan dan orang biasa. Ini memiliki keuntungan menghindari kebutuhan akan atribut partisi. Anda bisa melakukan ini dengan atau tanpa tabel tipe super. Menggunakan tabel tipe super memungkinkan Anda menggunakan batasan deklaratif untuk menegakkan keunikan. Kalau tidak, ini harus ditegakkan secara prosedural. Solusi ini dinormalisasi tetapi itu tidak akan memungkinkan Anda untuk mempertahankan integritas referensial deklaratif kecuali Anda menyimpan tabel tipe-super. Masih tidak melakukan apa pun untuk menghindari logika pengambilan kompleks.
Karena itu Anda dapat melihat bahwa tidak benar-benar mungkin untuk memiliki desain bersih yang mengikuti semua aturan, sementara pada saat yang sama menjaga pengambilan data Anda tetap sederhana. Anda harus memutuskan di mana trade-off Anda akan berada.
sumber
corporation_id
danperson_id
kemudian Anda pada dasarnya akan memiliki solusi sub-mengetik, kecuali bahwa tabel tipe super akan dibagi menjadi dua dan kunci asing akan dibalik, sehingga orang tidak dapat memiliki banyak akun. Jenis ini mengalahkan tujuannya.RefID
dan diRefTable
manaRefTable
id tetap yang mengidentifikasi tabel target. Ada banyak kasus penggunaan untuk jenis kunci ini dan banyak mempertahankan 10 atau lebih tabel asosiasi / subtipe untuk menegakkan integritas. Untuk kasus-kasus itu saya buat inikey
sendiri.