Anda memiliki setidaknya lima opsi ini untuk memodelkan hierarki tipe yang Anda uraikan:
Warisan Satu Tabel : satu tabel untuk semua jenis Produk, dengan kolom yang cukup untuk menyimpan semua atribut dari semua jenis. Ini berarti banyak kolom, yang sebagian besar NULL pada setiap baris yang diberikan.
Class Table Inheritance : satu tabel untuk Products, menyimpan atribut yang umum untuk semua jenis produk. Kemudian satu tabel per jenis produk, menyimpan atribut khusus untuk jenis produk itu.
Warisan Tabel Beton : tidak ada tabel untuk atribut Produk umum. Sebagai gantinya, satu tabel per jenis produk, menyimpan atribut produk umum, dan atribut spesifik produk.
LOB seri : Satu tabel untuk Produk, menyimpan atribut yang sama untuk semua jenis produk. Satu kolom tambahan menyimpan BLOB data semi-terstruktur, dalam format XML, YAML, JSON, atau lainnya. BLOB ini memungkinkan Anda untuk menyimpan atribut khusus untuk setiap jenis produk. Anda dapat menggunakan Pola Desain mewah untuk menggambarkan ini, seperti Fasad dan Memento. Tetapi terlepas dari Anda memiliki segumpal atribut yang tidak dapat dengan mudah ditanyakan dalam SQL; Anda harus mengambil seluruh gumpalan kembali ke aplikasi dan mengatasinya di sana.
Nilai Atribut-Atribut : Satu tabel untuk Produk, dan satu tabel yang memutar atribut ke baris, bukan kolom. EAV bukan desain yang valid sehubungan dengan paradigma relasional, tetapi banyak orang tetap menggunakannya. Ini adalah "Pola Properti" yang disebutkan oleh jawaban lain. Lihat pertanyaan lain dengan tag eav di StackOverflow untuk beberapa jebakan.
Saya telah menulis lebih banyak tentang ini dalam presentasi, Pemodelan Data yang Dapat Diperpanjang .
Pikiran tambahan tentang EAV: Meskipun banyak orang tampaknya menyukai EAV, saya tidak. Sepertinya solusi yang paling fleksibel, dan karena itu yang terbaik. Namun, perlu diingat pepatah TANSTAAFL . Berikut adalah beberapa kelemahan EAV:
- Tidak ada cara untuk membuat kolom wajib (setara dengan
NOT NULL
).
- Tidak ada cara untuk menggunakan tipe data SQL untuk memvalidasi entri.
- Tidak ada cara untuk memastikan bahwa nama atribut dieja secara konsisten.
- Tidak ada cara untuk meletakkan kunci asing pada nilai atribut yang diberikan, misalnya untuk tabel pencarian.
- Mengambil hasil dalam tata letak tabel konvensional itu rumit dan mahal, karena untuk mendapatkan atribut dari beberapa baris yang perlu Anda lakukan
JOIN
untuk setiap atribut.
Tingkat fleksibilitas yang diberikan EAV Anda memerlukan pengorbanan di bidang lain, mungkin membuat kode Anda menjadi kompleks (atau lebih buruk) daripada menyelesaikan masalah asli dengan cara yang lebih konvensional.
Dan dalam kebanyakan kasus, tidak perlu memiliki tingkat fleksibilitas seperti itu. Dalam pertanyaan OP tentang jenis produk, jauh lebih mudah untuk membuat tabel per jenis produk untuk atribut spesifik produk, sehingga Anda memiliki beberapa struktur yang konsisten diberlakukan setidaknya untuk entri dari jenis produk yang sama.
Saya akan menggunakan EAV hanya jika setiap baris harus diizinkan memiliki serangkaian atribut yang berbeda. Ketika Anda memiliki serangkaian jenis produk yang terbatas, EAV berlebihan. Class Table Inheritance akan menjadi pilihan pertama saya.
Pembaruan 2019: Semakin saya melihat orang menggunakan JSON sebagai solusi untuk masalah "banyak atribut khusus", semakin saya tidak suka solusi itu. Itu membuat kueri terlalu rumit, bahkan ketika menggunakan fungsi JSON khusus untuk mendukungnya. Dibutuhkan lebih banyak ruang penyimpanan untuk menyimpan dokumen JSON, dibandingkan menyimpan dalam baris dan kolom normal.
Pada dasarnya, tidak ada solusi ini yang mudah atau efisien dalam database relasional. Seluruh gagasan memiliki "atribut variabel" pada dasarnya bertentangan dengan teori relasional.
Apa yang terjadi adalah Anda harus memilih salah satu solusi berdasarkan yang paling tidak buruk untuk aplikasi Anda . Karena itu Anda perlu tahu bagaimana Anda akan meminta data sebelum Anda memilih desain database. Tidak ada cara untuk memilih satu solusi yang "terbaik" karena salah satu solusi yang terbaik untuk aplikasi tertentu.