Saya merancang basis data untuk digunakan oleh tim penjualan kami sebagai alat mengutip pekerjaan cepat. Saya ingin umpan balik pada aspek tertentu dari desain.
Kutipan pada dasarnya dibangun dengan memilih daftar 'majelis' yang telah ditentukan masing-masing dengan harga yang disepakati. Tampilan bentuk utama yang disederhanakan terlihat seperti ini:
+------------ --- ---+
| Assembly options |
+------------+------------+----------+------------+---+---+---+ --- +--+
| assembly ▼ | unit cost | quantity | total cost | 1 | 2 | 3 | |50|
+------------+------------+----------+------------+---+---+---+ --- +--+
| VSD55 | £10'000 | 2 | £25'500 | 1 | 1 | | | |
| RDOL2.2 | £2'000 | 1 | £1'500 | | 1 | | | |
| DOL5.0 | £1'000 | 1 | £1'200 | | | 1 | | |
+------------+------------+----------+------------+---+---+---+ --- +--+
Pengguna memilih rakitan yang telah ditentukan, memasukkan kuantitas dan memilih 'opsi' yang diperlukan. Setiap unit berpotensi memiliki hingga 50 opsi yang tersedia. Opsi juga merupakan rakitan yang sudah ditentukan sebelumnya (sub-rakitan) dengan harga sendiri. 'Biaya total' untuk setiap baris dihitung sebagai (biaya perakitan utama * kuantitas) + biaya opsi apa pun.
Ketika pengguna memindahkan kursor ke kotak pilihan, nama & harga opsi tersebut diketahui oleh mereka.
Sekarang di sinilah menjadi rumit. Setiap majelis memiliki daftar opsi yang tersedia sendiri. yaitu opsi 1 untuk 'VSD55' mewakili sub-rakitan yang berbeda dari opsi 1 untuk DOL5.0.
Sejauh majelis pergi di sini adalah tabel sederhana yang saya gunakan:
+-----------------+ +------------------------+ +-----------------------------+
| assembly | | assembly_option | | assembly_option_link |
+-----------------+ +------------------------+ +-----------------------------+
| assembly_id (PK)| | assembly_option_id (PK)| | assembly_option_link_id (PK)|
| assembly_name | | assembly_option_name | | assembly_id (FK) |
| unit_cost | | option_number | | assembly_option_id (FK) |
+-----------------+ | unit_cost | +-----------------------------+
+------------------------+
Tabel 'assembly_option_link' pada dasarnya menentukan opsi mana yang tersedia untuk setiap perakitan.
Sekarang untuk tabel 'kutipan':
+-----------------+ +------------------------+
| quote | | quote_assembly |
+-----------------+ +------------------------+
| quote_id (PK) | | quote_assembly_id (PK) |
| quote_name | | assembly_id (FK) |
+-----------------+ | quantity |
+------------------------+
Sekarang bagian yang sulit adalah bagaimana menyimpan opsi yang dipilih. Haruskah saya memperluas tabel 'quote_assembly' dengan semua 50 bidang opsi meskipun ini melanggar aturan normalisasi. Perakitan tidak akan pernah dipilih dengan semua 50 opsi sehingga ini tampaknya sangat tidak efisien. Di sisi positifnya, solusi ini memungkinkan formulir entri pengguna untuk memetakan langsung ke tabel membuat coding mudah.
Solusi 'dinormalisasi' saya pikir akan membuat tabel lain seperti ini:
+------------------------------+
| quote_assembly_option |
+------------------------------+
| quote_assembly_option_id (PK)|
| quote_assembly_id (FK) |
| assembly_option_id (FK) |
| quantity |
+------------------------------+
Solusi ini berarti hanya opsi yang dipilih yang disimpan. Selain itu, daripada menyimpan option_number, saya dapat menyimpan 'assembly_option_id' yang sebenarnya. Ini kemudian membuat menghitung biaya penawaran total lebih mudah karena saya tidak perlu mengkonversi antara 'option_number' dan 'assembly_option_id' untuk mencari biaya opsi perakitan. Namun kelemahan utama dengan solusi ini adalah tidak cocok dengan formulir entri pengguna. Saya pikir saya perlu menerapkan beberapa pengkodean mewah untuk antarmuka formulir dengan tabel.
Adakah yang bisa memberikan saran desain di sini? Saya harap saya sudah menjelaskan diri saya dengan cukup baik.
INFO LEBIH LANJUT
Ini juga merupakan laporan kutipan terperinci yang memperluas setiap opsi yang dipilih sebagai item baris terpisah di bawah unit utama. Sebagai contoh:
+---------------------------------+------------+----------+------------+
| assembly | unit cost | quantity | total cost |
+---------------------------------+------------+----------+------------+
| VSD55 | £10'000 | 2 | £20'000 |
| - Seal leak protection | £ 5'000 | 1 | £ 5'000 | <-option 1
| - Motor over temp protection | £ 500 | 1 | £ 500 | <-option 2
+---------------------------------+------------+----------+------------+
| | | | £25'500 |
+---------------------------------+------------+----------+------------+
Opsi terakhir yang Anda berikan adalah cara saya akan menggunakannya. Dan kembalikan dua tabel yang dikelompokkan, satu untuk "baris utama" dan satu untuk baris yang dikumpulkan "apakah ada" untuk 50 kolom. Dengan asumsi Anda dapat memetakan opsi untuk ID kolom yang sesuai itu cukup mudah (sepertinya Anda bisa tanpa terlalu banyak kesulitan).
Itu akan cukup mudah untuk iterasi, dengan asumsi bahasa seperti C #, di mana Anda memiliki LINQ tersedia, dll. Itu cukup mudah untuk dilakukan, bahkan jika mereka melibatkan sedikit perulangan (itu adalah kode UI, itu harus dilakukan di beberapa titik ). Atau Anda bisa melakukan poros di basis data sebelum kembali ... itu akan lebih cepat. Tetapi tetap akan mempertahankan kompleksitas.
Tetapi desain Anda tidak terdengar suara bagi saya.
sumber
Menambahkan meja tambahan Anda sepertinya juga cukup masuk akal bagi saya.
Ketika berhadapan dengan masalah yang sama di ujung saya, saya menjelajahi menyimpan pohon di tabel order_lines. Jika Anda menganggap hal serupa, saya punya:
parent_id
bidang tambahan untukorder_lines
, dan kunci asing sehingga(parent_id, product_id)
akan referensi(order_line_id, product_id)
Batasan pemeriksaan untuk membuat memiliki opsi akan menyiratkan orangtua (dalam kasus saya
check((option_id is not null) = (parent_id is not null))
).Dengan kata lain saya membiarkan UI memiliki kata tentang bagaimana hal-hal harus disimpan:
Dari sudut pandang pengkodean UI rasanya benar. Tetapi dengan cepat merasa salah dari sudut pandang aturan bisnis, karena itu memperkenalkan berbagai masalah di ujung jalan. (Saya harus berurusan dengan segala macam kasus khusus dalam pemicu.)
Jadi tidak direkomendasikan ... Sejauh saya pernah mengalami kasus serupa, pendekatan Anda saat ini tidak akan terlalu bermasalah.
sumber