Apakah akan membuat tabel terpisah atau tidak untuk berbagai jenis produk?

25

Saya sedang dalam proses merancang database dan saya memiliki pemikiran kedua tentang keputusan desain awal saya ...

Jenis produk adalah sebagai berikut ... Model, suku cadang, kit dan opsi suku cadang.

Opsi A (desain pertama): Saya berencana memiliki tabel terpisah untuk jenis produk di atas. Saya akan mengatakan sekitar 75% dari bidang akan sama di setiap tabel.

Saya membuat setiap jenis produk sebagai tabel terpisah karena asosiasi yang saya perlu buat di antara mereka. Misalnya, Model dapat memiliki banyak opsi dan opsi dapat memiliki banyak model. Opsi juga dapat memiliki banyak bagian dan sebagian dapat memiliki banyak opsi ... dan seterusnya ...

Opsi B: Alih-alih memiliki tabel terpisah, saya dapat membuat tabel yang disebut Produk yang mencakup model, komponen, kit pengganti, dan opsi. Saya dapat memiliki satu jenis bidang yang disebut untuk membedakan antara model, opsi, dll. Saya kira sisi bawah adalah beberapa bidang tidak akan pernah digunakan (nol kiri) untuk jenis produk tertentu. Saya menduga ini adalah di mana "bukan praktik terbaik" akan ikut bermain ..

Opsi B akan sangat mengurangi kompleksitas desain db. Saya juga tidak perlu khawatir tentang referensi banyak tabel ketika mengeluarkan data untuk permintaan ...

pembayaran
sumber
2
Pada poin ini saya sarankan Anda membuat spreadsheet yang meniru tata letak tabel Anda dan mengisinya dengan data. Ini akan memaparkan kelemahan yang mungkin ada.
Michael Riley - AKA Gunny
Bagaimana Anda akan menunjukkan kunci asing pada produk yang berbeda jika mereka berada di tabel yang berbeda? Tolong baca di warisan tabel.
Neil McGuigan

Jawaban:

8

Jika ini adalah keputusan desain saya, saya mungkin akan menggunakan lebih banyak 'Opsi C' (opsi yang dimodifikasi a).

Pertama, mengapa tidak 'Opsi B':

Untuk satu hal, saya suka kejelasan bahwa setiap produk memiliki tabel sendiri. Jika itu semua satu tabel besar dengan bidang untuk menentukan jenisnya, hubungannya tidak jelas.

Untuk yang lain, strategi pengindeksan akan selalu mengharuskan bidang jenis itu untuk didaftar. Karena hanya 4 jenis, kardinalitas indeks sangat rendah ( SELECT * FROM product_table WHERE type='X'pada dasarnya melakukan pemindaian tabel penuh)

Opsi C

  • Buat tabel induk yang hanya memegang kolom yang berbagi semua jenis
  • Buat setiap jenis produk sebagai tabelnya sendiri dengan kolomnya masing-masing, dengan satu tambahan: Tautan ke tabel induk
  • Buat setiap tabel 'tautan': Product_Option, Model_option, dll dengan tautan ke kunci masing-masing.
  • Bagi mereka yang memiliki tautan timbal balik (MODEL_OPTION, OPTION_MODEL) lanjutkan dan buat tabel itu juga. Ini akan menambah kejelasan dalam gabungan Anda untuk siapa pun yang melihatnya.

The downside adalah kompleksitas memastikan untuk menghindari anak yatim ketika hal-hal diperbarui / dihapus, dan pada awalnya merancang pertanyaan yang menggunakan tabel ini.

Derek Downey
sumber
5
Hanya ada 4 jenis sekarang, tetapi bagaimana jika lebih banyak ditambahkan nanti? Saya yakin tabel produk utama Amazon pada awalnya disebut "Buku" tetapi apakah Anda pikir mereka memiliki tabel terpisah untuk setiap jenis produk sekarang? Saya tidak berpikir setiap jenis harus memiliki tabel sendiri tetapi Anda bisa menggunakan model EAV untuk properti tambahan yang masing-masing jenis mungkin memiliki kesamaan.
Aaron Bertrand
1
@Aaron Fair point tentang peningkatan jenis produk di masa depan. Jika skenario ini dapat berkembang hingga 10+ jenis produk, saya akan mempertimbangkan kembali. Tapi, saya merasa tabel produk tertentu adalah pilihan desain yang adil untuk sejumlah kecil jenis produk.
Derek Downey
1
Opsi C: Apakah perlu memiliki tabel tautan? Saya akan membayangkan Product_Option PK akan cocok dengan PK dari tabel Produk dan itu akan membuat asosiasi untuk menghubungkan kedua tabel.
pembayaran
Dengan menggunakan Product_option sebagai contoh, skema tersebut adalah (dalam pikiran saya): id, productID, optionID. productIDakan menjadi FK untuk product.id, dan optionIDmerupakan FK untuk option.id. Itulah yang saya maksud dengan tabel tautan. Dan ya, desain ini diperlukan untuk memungkinkan satu produk terhubung ke beberapa opsi.
Derek Downey
Baik, saya mengerti. Saya salah membaca apa yang Anda ketikkan .. Ups.
pembayaran
7

Saya sarankan Anda mulai dengan model relasional yang "benar", opsi Anda A. Jika penggunaan khas model itu mengarahkan Anda untuk melakukan denormalisasi di beberapa area, jangan takut untuk melakukannya.

Saya sedang berdiskusi dengan seorang kolega minggu lalu bagaimana desain skema sering dianggap sebagai sesuatu yang dibuat mati-matian dan tidak pernah bisa berubah. Aneh, mengingat bagaimana refactoring dalam praktik yang diterima di setiap lapisan aplikasi, bahwa refactoring skema database masih dipandang tidak praktis.

Jika antarmuka ke database dirancang dengan baik, tidak ada yang menghentikan Anda dari mengadaptasi skema saat Anda mempelajari lebih lanjut tentang pola penggunaan sistem.

Mark Storey-Smith
sumber
2

Ini terdengar sangat mirip dengan Bills of material / multiple kardinalities heirarcy yang dijelaskan Paul Neilsen di Bab 17 dari The SQL Server 2008 Bible .

Seluruh bab adalah bacaan yang sangat baik dan bagian spesifik yang membahas masalah banyak-ke-banyak Anda dapat ditemukan di halaman 416-419.

Ini adalah diskusi terbaik yang pernah saya lihat mengenai tipe desain data yang meledak .

Michael Riley - AKA Gunny
sumber
Solusi ini terlihat mirip dengan opsi B (jika saya memahaminya dengan benar, yang saya tidak yakin saya lakukan). Saya akan memiliki tabel master (Produk) dan tabel "tautan" (alias tabel yang berdekatan / BillsofMaterials) untuk membuat asosiasi antara model, opsi, kit, dll. Apakah itu benar?
pembayaran
Saya pikir masalah ini kabur karena pilihan. Mari kita mengambil opsi keluar dari diskusi sebentar. Bagian adalah unit terkecil. Sekelompok bagian membuat model. Sekelompok komponen pengganti dalam bentuk kit membentuk subset dari model. Sejauh ini baik. Sekarang bagian memiliki opsi mari kita asumsikan demi kesederhanaan ini mencakup dua kategori warna (hitam, merah, krom) dan bahan (logam, kayu, plastik). Anda juga menyebutkan bahwa model memiliki opsi. Apakah opsi model terpisah dari opsi bagian atau apakah model hanya tampaknya memiliki opsi karena bagian membuat model berbeda?
Michael Riley - AKA Gunny
Bagian tidak memiliki "opsi" dalam desain saya. Saya mendefinisikan opsi sebagai sesuatu yang berjalan pada model yang menyediakannya dengan fungsionalitas yang diperluas. Opsi terdiri dari bagian-bagian. Model dapat memiliki banyak opsi berbeda. Sebuah opsi dapat sesuai dengan banyak model yang berbeda juga.
pembayaran pada
Bukan itu cara Anda mengutarakan pertanyaan Anda. "Misalnya, Model dapat memiliki banyak opsi dan opsi dapat memiliki banyak model. Opsi juga dapat memiliki banyak bagian dan sebagian dapat memiliki banyak opsi ... dan seterusnya ..." Pada poin ini saya sarankan Anda buat spreadsheet yang meniru tata letak tabel Anda dan mengisinya dengan data. Ini akan memaparkan kelemahan yang mungkin ada.
Michael Riley - AKA Gunny
0

Jika Anda dapat membayangkan skenario yang mungkin terjadi di mana akan sering terjadi kueri yang melintasi keempat jenis produk (dan itu tampaknya bagi saya), maka pilihan B Anda adalah yang terbaik.

Alih-alih meninggalkan banyak bidang nullable yang tidak terpakai dalam tabel Produk, mengapa tidak menambahkan tabel ModelProduct, tabel PartProduct, tabel ReplacementPartKitProduct, dan hanya memiliki bidang yang berbeda untuk jenis-jenis dalam tabel tersebut? Gunakan kunci utama yang sama pada tabel tersebut sebagai tabel Produk Anda. Bergabunglah dengan tabel Product and ModelProduct ketika Anda ingin bekerja dengan Model. Perlu menentukan apakah catatan Produk yang Anda miliki adalah Bagian? Lakukan saja penggabungan kiri dari Produk ke PartProduct, dan jika PartProduct. [PrimaryKey] bukan nol, Anda memiliki Bagian. Jika itu nol, itu bukan Bagian. Sebagai alternatif, Anda bisa menambahkan bidang ProductType ke tabel Produk.

Alan McBee
sumber
Bidang nol akan minimal, karena sekitar 75% bidang akan digunakan di setiap tabel. Saya kira saya lebih khawatir tentang hubungan antara jenis produk. Saya akan memiliki tiga atau lebih tabel tautan yang menunjuk ke tabel yang sama. Model_has_Option dua kunci utama, kedua id produk dari tabel produk, jika saya hanya menggunakan satu tabel untuk mewakili jenis produk. Saya lebih peduli apakah itu hal yang benar untuk dilakukan atau tidak.
pembayaran
Meskipun ada banyak faktor yang memengaruhi keputusan "benar", ada dua faktor luas yang perlu dipertimbangkan. 1: persyaratan kinerja keseluruhan; 2: kemampuan beradaptasi / kompleksitas / pemeliharaan. Salah satu dari keduanya mungkin sedikit lebih penting daripada yang lain. Jika Anda membutuhkan kecepatan, denormalkan dengan tetap menggunakan Opsi A. Anda akan memiliki duplikasi; itu yang diharapkan. Jika Anda perlu mengutak-atik skema secara teratur dan kecepatan bukanlah faktor yang paling penting, maka Opsi B. Anda mendapatkannya "benar" dengan mengetahui prioritas Anda, bukan dengan mengikuti "praktik terbaik orang lain."
Alan McBee