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.
@StoneHeart
Saya akan pergi di sini dengan EAV dan MVC sepanjang jalan.
@ Bill Karvin
Semua hal yang telah Anda sebutkan di sini:
menurut pendapat saya tidak termasuk dalam database sama sekali karena tidak ada database yang mampu menangani interaksi dan persyaratan pada tingkat yang tepat seperti bahasa pemrograman aplikasi.
Menurut pendapat saya menggunakan database dengan cara ini seperti menggunakan batu untuk memalu paku. Anda dapat melakukannya dengan batu tetapi bukankah Anda seharusnya menggunakan palu yang lebih tepat dan dirancang khusus untuk kegiatan semacam ini?
Masalah ini dapat diselesaikan dengan membuat beberapa pertanyaan tentang data parsial dan memprosesnya menjadi tata letak tabel dengan aplikasi Anda. Bahkan jika Anda memiliki 600GB data produk, Anda dapat memprosesnya dalam batch jika Anda memerlukan data dari setiap baris dalam tabel ini.
Menuju lebih jauh Jika Anda ingin meningkatkan kinerja kueri, Anda dapat memilih operasi tertentu seperti untuk mis. Pelaporan atau pencarian teks global dan mempersiapkan mereka tabel indeks yang akan menyimpan data yang diperlukan dan akan dibuat ulang secara berkala, katakanlah setiap 30 menit.
Anda bahkan tidak perlu khawatir dengan biaya penyimpanan data tambahan karena semakin murah dan lebih murah setiap hari.
Jika Anda masih khawatir dengan kinerja operasi yang dilakukan oleh aplikasi, Anda selalu dapat menggunakan Erlang, C ++, Go Language untuk melakukan pra-proses data dan kemudian hanya memproses data yang dioptimalkan lebih lanjut di aplikasi utama Anda.
sumber
you can always use Erlang, C++, Go Language to pre-process the data
Apa yang kamu maksud? Alih-alih DB, gunakan Go lang? Bisakah Anda menjelaskannya?Jika saya menggunakan
Class Table Inheritance
makna:Yang saya suka yang terbaik dari Saran Bill Karwin .. Saya bisa meramalkan satu kelemahan, yang akan saya coba jelaskan bagaimana menjaga agar tidak menjadi masalah.
Apa rencana darurat yang harus saya miliki ketika atribut yang hanya umum untuk 1 jenis, kemudian menjadi umum untuk 2, kemudian 3, dll?
Misalnya: (ini hanya contoh, bukan masalah saya yang sebenarnya)
Jika kita menjual furnitur, kita mungkin menjual kursi, lampu, sofa, TV, dll. Jenis TV mungkin merupakan satu-satunya jenis yang kita bawa yang memiliki konsumsi daya. Jadi saya akan meletakkan
power_consumption
atribut ditv_type_table
. Tetapi kemudian kita mulai membawa sistem Home theater yang juga memilikipower_consumption
properti. OK itu hanya satu produk lain jadi saya akan menambahkan bidang inistereo_type_table
juga karena itu mungkin paling mudah saat ini. Tetapi seiring berjalannya waktu kita mulai membawa lebih banyak dan lebih banyak barang elektronik, kita menyadari bahwapower_consumption
itu cukup luas sehingga seharusnya ada di dalamnyamain_product_table
. Apa yang harus saya lakukan sekarang?Tambahkan bidang ke
main_product_table
. Tulis skrip untuk mengulang melalui elektronik dan menempatkan nilai yang benar dari masingtype_table
- masing kemain_product_table
. Lalu jatuhkan kolom itu dari masing-masingtype_table
.Sekarang Jika saya selalu menggunakan
GetProductData
kelas yang sama untuk berinteraksi dengan database untuk menarik info produk; maka jika ada perubahan dalam kode sekarang perlu refactoring, mereka harus ke Kelas itu saja.sumber
Anda dapat memiliki tabel Produk dan tabel ProductAdditionInfo yang terpisah dengan 3 kolom: ID produk, nama info tambahan, nilai info tambahan. Jika warna digunakan oleh banyak tetapi tidak semua jenis Produk Anda bisa memilikinya menjadi kolom nullable di tabel Produk, atau cukup taruh di ProductAdditionalInfo.
Pendekatan ini bukan teknik tradisional untuk database relasional, tetapi saya telah melihatnya banyak digunakan dalam praktik. Itu bisa fleksibel dan memiliki kinerja yang baik.
Steve Yegge menyebutnya pola Properti dan menulis posting panjang tentang menggunakannya.
sumber
3 columns: product ID, additional info name, additional info value
saya mengerti konsep itu. Dan saya benar-benar melakukan ini sebelumnya, dan mengalami masalah. Namun, saya tidak ingat pada saat itu apa masalah itu.