Saya sedang berupaya memperbarui basis data produk situs web kami. Ini dibangun di MySQL tetapi ini lebih merupakan pertanyaan pola desain database umum.
Saya berencana beralih ke pola Supertype / Subtype. Basis data kami saat ini / sebelumnya sebagian besar merupakan tabel tunggal yang memiliki data pada satu jenis produk. Kami sedang memperluas penawaran produk kami untuk memasukkan produk yang berbeda.
Draf desain baru ini seperti ini:
Product product_[type] product_attribute_[name]
---------------- ---------------- ----------------------------
part_number (PK) part_number (FK) attributeId (PK)
UPC specific_attr1 (FK) attribute_name
price specific_attr2 (FK)
... ...
Saya punya pertanyaan tentang tabel atribut produk. Idenya di sini adalah produk dapat memiliki daftar atribut yang diberikan seperti warna: merah, hijau, biru, atau bahan: plastik, kayu, krom, aluminium, dll.
Daftar ini akan disimpan dalam sebuah tabel dan kunci utama (PK) untuk item atribut itu akan digunakan dalam tabel produk tertentu sebagai kunci asing (FK).
(Buku Martin Fowler, Pola Arsitektur Aplikasi Perusahaan menyebutnya " Pemetaan Kunci Asing ")
Ini memungkinkan antarmuka situs web untuk menarik daftar atribut untuk tipe atribut yang diberikan dan meludahkannya dalam menu pilih tarik turun atau elemen UI lainnya. Daftar ini dapat dianggap sebagai daftar "nilai atribut".
Jumlah sambungan yang akhirnya terjadi ketika menarik produk tertentu tampak berlebihan bagi saya. Anda harus bergabung dengan setiap tabel atribut produk ke produk sehingga Anda bisa mendapatkan bidang atribut itu. Umumnya, bidang itu mungkin hanya berupa string (varchar) untuk namanya.
Pola desain ini akhirnya membuat sejumlah besar tabel dan Anda berakhir dengan tabel untuk setiap atribut. Satu ide untuk mengatasi hal ini adalah membuat tabel “grab bag” untuk semua atribut produk. Sesuatu seperti ini:
product_attribute
----------------
attributeId (PK)
name
field_name
Dengan cara ini, meja Anda mungkin terlihat seperti ini:
1 red color
2 blue color
3 chrome material
4 plastic material
5 yellow color
6 x-large size
Ini bisa membantu mengurangi creep meja tetapi tidak mengurangi jumlah gabungan dan rasanya sedikit salah menggabungkan begitu banyak jenis yang berbeda menjadi satu tabel. Tetapi Anda akan bisa mendapatkan semua atribut "warna" yang tersedia dengan cukup mudah.
Namun, mungkin ada atribut yang memiliki bidang lebih dari sekadar "nama" seperti nilai RGB warna. Ini akan memerlukan atribut khusus untuk memiliki tabel lain atau memiliki bidang tunggal untuk pasangan nama: nilai (yang memiliki kelemahan sendiri).
Pola desain terakhir yang dapat saya pikirkan adalah menyimpan nilai atribut aktual dalam tabel produk tertentu dan tidak memiliki "tabel atribut" sama sekali. Sesuatu seperti ini:
Product product_[type]
---------------- ----------------
part_number (PK) part_number (FK)
UPC specific_attr1
price specific_attr2
... ...
Alih-alih Kunci Asing ke tabel lain, itu akan berisi nilai aktual seperti:
part_number color material
----------- ----- --------
1234 red plastic
Ini akan menghilangkan gabungan dan mencegah merayap meja (mungkin?). Namun, ini mencegah memiliki "daftar resmi" atribut. Anda bisa mengembalikan semua nilai yang saat ini dimasukkan untuk bidang tertentu (yaitu: warna) tetapi ini juga menghilangkan gagasan memiliki "daftar nilai" yang diotorisasi untuk atribut yang diberikan.
Untuk memiliki daftar itu, Anda masih harus membuat tabel atribut "grab bag" atau memiliki beberapa tabel (table creep) untuk setiap atribut.
Ini menciptakan kelemahan yang lebih besar (dan mengapa saya tidak pernah menggunakan pendekatan ini) sekarang memiliki nama produk di beberapa lokasi.
Jika Anda memiliki nilai warna "merah" di "tabel atribut utama" dan juga menyimpannya di tabel "product_ [type]", pembaruan ke tabel "master" akan menyebabkan masalah integritas data potensial jika aplikasi tidak perbarui semua catatan dengan nilai lama di tabel "product_type" juga.
Jadi, setelah penjelasan saya yang panjang lebar dan analisis skenario ini, kesadaran saya adalah bahwa ini bukan skenario yang tidak biasa dan bahkan mungkin ada nama untuk jenis situasi seperti ini.
Apakah ada solusi yang diterima secara umum untuk tantangan desain ini? Apakah jumlah gabungan yang berpotensi besar dapat diterima jika tabelnya relatif kecil? Apakah menyimpan nama atribut, alih-alih atribut PK dapat diterima dalam beberapa situasi? Apakah ada solusi lain yang tidak saya pikirkan?
Beberapa catatan tentang basis data / aplikasi produk ini:
- Produk tidak sering diperbarui / ditambahkan / dihapus
- Atribut tidak sering diperbarui / ditambahkan / dihapus
- Tabel ini paling sering ditanyakan untuk membaca / mengembalikan informasi
- Caching sisi server diaktifkan untuk men-cache hasil dari kueri / hasil yang diberikan
- Saya berencana memulai dengan hanya satu jenis produk dan memperluas / menambah yang lain dari waktu ke waktu dan akan berpotensi 10+ jenis yang berbeda