it-swarm.it

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

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 indicati. 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 avere tabelle separate, potrei 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 ...

25
payling

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. Poiché sono solo 4 tipi, la cardinalità dell'indice è estremamente bassa (SELECT * FROM product_table WHERE type='X' sta fondamentalmente eseguendo comunque 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 tabella propria con le sue singole colonne, con un extra: un collegamento 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.

8
Derek Downey

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 di come i progetti di schemi sono spesso considerati qualcosa che è incastonato nella 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 poco pratico.

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.

7

Sembra molto simile alla distinte materiali/cardinalità multiple eredità che Paul Neilsen descrive in capitolo 17 di La Bibbia di SQL Server 2008 .

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

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

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.

0
Alan McBee