Se creare o meno tabelle separate per diversi tipi di prodotto?


25

Sto progettando un database e sto ripensando alle mie decisioni iniziali di progettazione ...

I tipi di prodotto sono i seguenti ... Modelli, parti, kit di parti di ricambio e opzioni.

Opzione A (primo progetto): avevo in programma di avere tabelle separate per i tipi di prodotto sopra elencati. Direi che circa il 75% dei campi sarebbe lo stesso in ogni tabella.

Ho creato ogni tipo di prodotto come tabelle separate a causa delle associazioni che devo creare tra di loro. Ad esempio, un modello può avere molte opzioni e un'opzione può avere molti modelli. Un'opzione può anche avere molte parti e una parte può avere molte opzioni ... e così via ...

Opzione B: Invece di disporre di tabelle separate, è possibile creare una tabella denominata Prodotto che comprende modelli, parti, kit di parti di ricambio e opzioni. Potrei avere un campo chiamato type per distinguere tra modello, opzioni, ecc. Suppongo che un lato negativo sia che diversi campi non sarebbero mai stati usati (lasciati nulli) per alcuni tipi di prodotto. Immagino che qui entrerebbero in gioco "non le migliori pratiche".

L'opzione B ridurrebbe notevolmente la complessità del progetto db. Inoltre non dovrei preoccuparmi di fare riferimento a un mucchio di tabelle quando si estraggono i dati per le query ...


2
A questo proposito ti suggerisco di creare fogli di calcolo che modifichino il layout della tabella e li riempiano di dati. Ciò esporrà eventuali punti deboli che possono esistere.
Michael Riley - AKA Gunny

Come indicherete le chiavi esterne su prodotti diversi se si trovano in tabelle diverse? Leggi l'eredità della tabella per favore.
Neil McGuigan,

Risposte:


8

Se questa fosse la mia decisione di progettazione, probabilmente sceglierei più di un'opzione C (opzione modificata a).

Innanzitutto, perché non "Opzione B":

Per prima cosa, mi piace la chiarezza che ogni prodotto ha le proprie offerte da tavola. Se è tutta una grande tabella con un campo per determinare il tipo, la relazione non è così chiara.

Per un altro, la strategia di indicizzazione richiederebbe sempre che quel campo di tipo fosse elencato. Dato che sono solo 4 tipi, la cardinalità dell'indice è estremamente bassa ( SELECT * FROM product_table WHERE type='X'fondamentalmente sta comunque eseguendo una scansione della tabella completa)

Opzione C

  • Crea una tabella padre che contiene solo le colonne condivise da tutti i tipi
  • Crea ogni tipo di prodotto come la sua tabella con le sue singole colonne, con un extra: un link alla tabella padre
  • Creare ogni tabella 'link': Product_Option, Model_option, ecc. Con collegamenti alle rispettive chiavi.
  • Per quelli con collegamenti reciproci (MODEL_OPTION, OPTION_MODEL) vai avanti e crea anche quelle tabelle. Ciò aggiungerà chiarezza nei tuoi join per chiunque lo guardi.

Il rovescio della medaglia è la complessità di assicurarsi di evitare gli orfani quando le cose vengono aggiornate / eliminate e di progettare inizialmente le query che utilizzano queste tabelle.


5
Ora ci sono solo 4 tipi, ma cosa succede se ne vengono aggiunti altri in seguito? Sono sicuro che la tabella principale dei prodotti Amazon sia stata originariamente chiamata "Libri", ma pensi che abbiano una tabella separata per ogni tipo di prodotto ora? Non credo che ogni tipo dovrebbe avere una propria tabella, ma è possibile utilizzare un modello EAV per proprietà aggiuntive che ogni tipo potrebbe avere in comune.
Aaron Bertrand

1
@Aaron Fair point sul futuro aumento dei tipi di prodotti. Se questo scenario potesse presumibilmente espandersi a oltre 10 tipi di prodotti, riconsidererei. Tuttavia, ritengo che tabelle specifiche di prodotti siano una scelta progettuale equa per una piccola quantità di tipi di prodotti.
Derek Downey,

1
Opzione C: è necessaria una tabella dei collegamenti? Immagino che PK Product_Option corrisponda al PK della tabella Product e che creerebbe l'associazione per collegare entrambe le tabelle.
pagando il

Usando Product_option come esempio, lo schema sarebbe (nella mia mente): id, productID, optionID. productIDsarebbe un FK per product.id, ed optionIDè un FK per option.id. Questo è ciò che intendevo per tabella dei collegamenti. E sì, è necessario in questo progetto per consentire a un singolo prodotto di collegarsi a più opzioni.
Derek Downey,

Ok ho capito. Ho letto male quello che hai scritto .. Oops.
pagando il

7

Ti suggerirei di iniziare con il modello relazionale "corretto", la tua opzione A. Se l'uso tipico di quel modello ti porta alla denormalizzazione in alcune aree, non aver paura di farlo.

La scorsa settimana ho discusso con un collega su come i progetti di schemi sono spesso considerati qualcosa che è messo in pietra e che non può mai cambiare. È strano, considerando come il refactoring sia accettato nella pratica in ogni altro livello di un'applicazione, che il refactoring di uno schema di database sia ancora visto come impraticabile.

Se l'interfaccia per il database è ben progettata, non c'è nulla che ti impedisca di adattare lo schema mentre scopri di più sui modelli di utilizzo dei sistemi.


2

Questo suona molto simile all'eredità delle distinte materiali / cardinalità multiple che Paul Neilsen descrive nel capitolo 17 della Bibbia di SQL Server 2008 .

L'intero capitolo è un'ottima lettura e la sezione specifica che risolve il problema dei molti a molti si trova alle pagine 416-419.

Questa è la migliore discussione che ho visto riguardo al tipo di parti esplose del design dei dati.


Questa soluzione è simile all'opzione B (se la capisco correttamente, cosa che non sono sicuro di fare). Avrei una tabella principale (Prodotti) e una tabella "link" (aka tabella adiacente / BillsofMaterials) per creare le associazioni tra modelli, opzioni, kit, ecc. È corretto?
pagando il

Penso che il problema sia offuscato a causa delle opzioni. Prendiamo opzioni fuori discussione per un po '. Le parti sono l'unità più piccola. Un gruppo di parti costituisce un modello. Un gruppo di parti di ricambio sotto forma di kit costituisce un sottoinsieme del modello. Fin qui tutto bene. Ora le parti hanno opzioni, supponiamo per semplicità che comprende due categorie di colore (nero, rosso, cromato) e materiale (metallo, legno, plastica). Hai anche detto che i modelli hanno opzioni. Le opzioni del modello sono separate dalle opzioni della parte o i modelli sembrano avere solo opzioni perché le parti rendono i modelli diversi?
Michael Riley - AKA Gunny,

Le parti non hanno "opzioni" nel mio progetto. Definisco l'opzione come qualcosa che va su un modello che fornisce funzionalità estese. Un'opzione è composta da parti. Un modello può avere molte opzioni diverse. Un'opzione può adattarsi anche a molti modelli diversi.
pagamento

Non è così che hai formulato la tua domanda. Citazione: "Ad esempio, un modello può avere molte opzioni e un'opzione può avere molti modelli. Un'opzione può anche avere molte parti e una parte può avere molte opzioni ... e così via ..." A questo punto ti consiglio creare fogli di calcolo che semplificano il layout della tabella e li riempiono di dati. Ciò esporrà eventuali punti deboli che possono esistere.
Michael Riley - AKA Gunny

0

Se riesci a immaginare uno scenario probabile in cui ci sarebbero frequenti domande che attraversano tutti e quattro i tipi di prodotti (e questo mi sembra probabile), allora l'opzione B è la migliore.

Invece di lasciare molti campi nullable inutilizzati nella tabella Prodotto, perché non aggiungere una tabella ModelProduct, una tabella PartProduct, una tabella ReplacementPartKitProduct e avere solo i campi che sono distinti per quei tipi in quelle tabelle? Utilizzare la stessa chiave primaria su quelle tabelle della tabella dei prodotti. Unisciti alla tabella Product and ModelProduct quando vuoi lavorare con i modelli. Devi determinare se il record del prodotto che hai è una parte? Basta eseguire un join sinistro da Product a PartProduct e, se PartProduct. [PrimaryKey] non è null, si dispone di una parte. Se è nullo, non è una parte. In alternativa, è possibile aggiungere un campo ProductType alla tabella Product.


I campi null sarebbero minimi, poiché circa il 75% dei campi verrebbe utilizzato in ogni tabella. Immagino di essere più preoccupato per le relazioni tra i tipi di prodotto. Avrò circa tre tabelle di link che puntano alla stessa tabella. Model_has_Option due chiavi primarie, entrambi ID prodotto della tabella prodotti, se dovessi usare solo una tabella per rappresentare i tipi di prodotto. Sono più preoccupato se questa è la cosa giusta da fare o no.
pagando il

Mentre ci sono molti fattori che influenzano la decisione "giusta", ci sono due grandi fattori da considerare. 1: requisiti generali di prestazione; 2: adattabilità / complessità / manutenibilità. Uno di questi due probabilmente è un po 'più importante dell'altro. Se hai bisogno di velocità, denormalizza attenendosi all'opzione A. Avrai la duplicazione; è previsto. Se hai bisogno di giocherellare con lo schema su base regolare e la velocità non è il fattore più importante, quindi l'opzione B. Lo ottieni "giusto" conoscendo le tue priorità, non aderendo alle "migliori pratiche di qualcun altro".
Alan McBee,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.