Apakah praktik yang buruk untuk memiliki beberapa hubungan satu-ke-satu yang saling eksklusif?


38

Katakanlah, meja carmemiliki hubungan satu-ke-satu ke meja electric_car, gas_cardan hybrid_car. Jika caradalah electric_car, tidak bisa lagi muncul dalam gas_caratau hybrid_car, dll

Apakah ada yang salah dengan desain seperti itu? Beberapa masalah yang mungkin terjadi di ujung jalan?

Jawaban:


59

Berbagai jenis mobil adalah contoh masalah umum yang muncul berulang kali dalam pemodelan data. Ini disebut "generalisasi / spesialisasi" dalam pemodelan ER, dan "superclass / subclass" dalam pemodelan objek.

Pemodel objek menggunakan fitur warisan yang dibangun ke dalam model objek untuk menyelesaikan masalah dengan cukup mudah. Subclass hanya memperpanjang superclass.

Pemodel relasional dihadapkan pada suatu masalah. bagaimana cara mendesain tabel agar bisa meniru manfaat yang akan didapat dari warisan?

Teknik paling sederhana disebut pewarisan tabel tunggal . Data tentang semua jenis mobil dikelompokkan ke dalam satu tabel untuk mobil. Ada kolom, car_type, yang mengelompokkan semua mobil dari satu tipe. Tidak ada mobil yang dapat dimiliki lebih dari satu jenis. Jika kolom tidak relevan dengan, katakanlah, mobil listrik, kolom NULL akan ditinggalkan di baris yang berkaitan dengan mobil listrik.

Solusi sederhana ini bekerja dengan baik untuk kasus yang lebih kecil dan sederhana. Kehadiran banyak NULLs menambahkan sedikit ke overhead penyimpanan, dan sedikit untuk mengambil overhead. Pengembang mungkin harus belajar logika tiga nilai SQL jika tes boolean dilakukan pada kolom nullable. Ini bisa membingungkan pada awalnya, tetapi orang terbiasa dengannya.

Ada teknik lain, yang disebut pewarisan tabel kelas . Dalam desain ini, ada tabel terpisah untuk gas_car, electric_car, dan hybrid_car, selain tabel gabungan, mobil, untuk semuanya. Saat Anda menginginkan semua data tentang jenis mobil tertentu, Anda bergabung dengan tabel mobil dengan tabel khusus yang sesuai. Ada lebih sedikit NULL dalam desain ini, tetapi Anda lebih banyak bergabung. Teknik ini bekerja lebih baik dalam kasus yang lebih besar dan lebih kompleks.

Ada teknik ketiga yang disebut kunci primer bersama. Teknik ini sering digunakan bersamaan dengan pewarisan tabel kelas. Tabel khusus untuk subclass memiliki, sebagai kunci utama, salinan kunci utama dari entri yang sesuai dalam tabel mobil. Kolom id ini dapat dideklarasikan sebagai kunci primer dan kunci asing.

Ini melibatkan sedikit pemrograman tambahan ketika mobil baru akan ditambahkan, tetapi itu membuat sambungannya sederhana, mudah, dan cepat.

Superclasses dan subclass terjadi setiap saat di dunia nyata. Jangan takut. Tetapi lakukan uji desain awal Anda untuk kinerja. Jika upaya pertama Anda sederhana dan sehat, Anda dapat mengubahnya untuk mempercepatnya.


3
Wow Terimakasih! Itu tepat pada apa yang saya coba cari tahu. Warisan tabel kelas tampaknya tepat seperti yang saya butuhkan. Saya mengubah jawaban yang saya terima untuk ini untuk pembaca masa depan karena saya pikir itu mencakup pertanyaan sepenuhnya, bukan hanya kasus saya.
Arthur Tarasov

6
Jawaban yang sangat bagus di sini. Satu tip: Dokumentasikan dengan cermat keputusan desain ini. Rute mana pun yang Anda ambil, tidak akan terlihat jelas ketika seseorang memeriksa struktur basis data. Beberapa database seperti Postgres memungkinkan Anda untuk mengikat komentar bersama dengan meta-data dari kolom, tabel, dan lainnya.
Basil Bourque

Anda tidak mengatasi pembatasan menjaga mobil listrik dari menjadi mobil hibrida. Anda memerlukan tabel terpisah untuk itu.
jmoreno

2
Kamu benar. Jika Anda menambahkan bidang car_type ke tabel mobil, Anda dapat membatasi mobil hanya milik satu jenis, dengan mengorbankan menyimpang dari normalisasi penuh. DBMS yang baik akan memungkinkan Anda menentukan batasan pemeriksaan yang akan mencegah mobil masuk ke lebih dari satu tabel khusus. Ada beberapa overhead dalam hal itu, Anda pergi untuk menambah mobil baru.
Walter Mitty

@WalterMitty tetapi tanpa car_typebidang, bagaimana Anda tahu tabel mana yang harus dicari detail saat mengambil data? Apakah Anda harus membaca ketiga tabel untuk melihat mana yang memiliki data tentang carcatatan spesifik itu ?
Josh Part

12

Tidak ada yang salah dengan memiliki sub-tipe entitas dalam model Anda sebanyak yang diperlukan untuk mencerminkan realitas data yang Anda coba modelkan. Pertanyaannya bukan apakah sub-tipe adalah praktik yang buruk. Masalahnya mungkin apakah itu model yang bagus ?

Misalnya, di bawah contoh Anda, apa yang Anda lakukan dengan sesuatu seperti Audi A4 eTron - yang merupakan plug-in hybrid? Apakah itu "mobil listrik" atau apakah itu "mobil hibrida"?

Pertanyaan lain yang harus Anda tanyakan pada diri sendiri adalah mengapa Anda mengetik sama sekali? Berapa banyak predikat berbeda yang Anda miliki di sub-tipe Anda? Apakah ada dari predikat ini dibagi di antara sub-tipe? Situasi bisa menjadi rumit.

Sub-pengetikan tidak digunakan dalam desain basis data untuk klasifikasi. Anda dapat melakukan klasifikasi dengan kode, kunci asing ke tabel kode, atau dengan bendera. Sub-pengetikan digunakan untuk memodelkan set predikat berbeda untuk berbagai jenis hal yang menarik. Jika Anda menggunakan sub-tipe hanya untuk klasifikasi maka itu praktik yang buruk.

Jika sub-tipe Anda memodelkan set predikat berbeda dengan jelas dan tidak ambigu untuk hal-hal yang dipedulikan oleh database Anda, maka ini adalah praktik yang sangat baik, terlepas dari berapa banyak sub-tipe yang Anda butuhkan.


Terima kasih, saya takut memasang jebakan untuk diri sendiri. Masalah saya adalah bahwa masing-masing subtipe akan memiliki banyak kolom. Beberapa akan tumpang tindih dan saya akan meletakkannya di carmeja, tetapi banyak yang tidak dan akan dimasukkan ke dalam tabel subtipe. Sebagai contoh, itu akan menjadi sesuatu seperti menyimpan bagian dasar dari tipe mobil. Mesin mobil listrik dapat memiliki seperti 100 bagian, mesin mobil gas 75 bagian, dan 125 bagian hybrid. 50 bagian akan menjadi umum dan disimpan dalam cars, sementara 50, 25, dan 75 akan berada di electric_car, gas_car, dan hybrid_carmeja
Arthur Tarasov
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.