2010-07-13 10 views
7

Ho un negozio online dove gli utenti possono avere piccoli negozi con i loro prodotti. Ciascuno di questi prodotti può avere domande ad esso associate e il proprietario del negozio ha la capacità di rispondere a tali domande. Questa informazione è memorizzata in 3 tabelle una tabella "Domande" (QuestionID, ProductID, ...), una tabella "Prodotti" (ProductID, ShopID, ...) e un "Negozio" (ShopID, OwnerID, ...) tavolo.È meglio memorizzare informazioni ridondanti o unire tabelle quando necessario in MySQL?

È meglio avere uno ShopID nella tabella "Domande" (per consentire al proprietario di un negozio di visualizzare tutte le sue domande) o unirsi a queste tre tabelle per ottenere domande corrispondenti a un determinato negozio?

+0

Grazie mille a tutti per le vostre utili risposte. Ero quasi convinto che sarebbe stato meglio archiviare informazioni ridondanti, ma oggi ho imparato qualcosa di nuovo. Alcuni hanno sottolineato che sarebbe meglio avere un rapporto M: M tra prodotti e negozi ma ciò non ha senso (int questo caso!) Perché i proprietari dei negozi sono completamente diversi (anche i costi di spedizione ecc. Sono completamente separati). Pertanto non è possibile che diversi negozi possano condividere un prodotto (anche se fosse lo stesso prodotto fisicamente per così dire). –

risposta

9

È quasi sempre preferibile unirsi ed evitare informazioni ridondanti. Dovresti solo denormalize quando devi farlo per raggiungere un obiettivo di rendimento e non puoi sapere se devi farlo finché non provi prima con le tabelle normalized.

Si noti che la denormalizzazione aiuta a migliorare le prestazioni di lettura a scapito del rallentamento delle scritture e rende più semplice per un errore di codifica i dati non sincronizzati (dal momento che si memorizza la stessa cosa in più di un posto devi essere sicuro di aggiornarlo tutto).

2

In genere è meglio evitare le informazioni ridondanti. Sembra che dovrebbe essere un join abbastanza economico da fare dato gli indici appropriati e non vorrei denormalizzare in questo modo a meno che non vedessi nei piani di query che il JOIN stava causando problemi (forse a causa del numero di record nelle tabelle)

È inoltre necessario considerare il rapporto tra letture e scritture. La denormalizzazione aiuterà le letture, ma aggiungerà un overhead alle scritture.

+0

il join sarà abbastanza economico solo per piccoli database. Se si sta considerando la cardinalità per un indice su shopID nella tabella prodotti, il tempo richiesto per l'adesione potrebbe essere significativo. –

+0

@narcisradu - Sì, ho dovuto ricorrere a questo prima, ma il punto che stavo facendo è che dovrebbe essere fatto solo quando i piani di esecuzione mostrano un caso per questo. –

1

Si dovrebbe avere una relazione molti a molti tra le domande e i prodotti:

questions_ref (question_id, question_code, domanda)

product_questions (pquestion_id, question_id_fk, product_id_fk)

prodotti (product_id, product_name, etc)

Se è possibile che il prodotto si trovi in ​​più di un negozio (che è certo), è necessario avere un rapporto molti a molti tra negozi e prodotti.

shop_products (sproduct_id, product_id_fk, shop_id_fk, sproduct_price, other_shop_specific_param)

negozi (shop_id, owner_id_fk, shop_name, ecc)

+0

Non penso che sia necessaria una relazione molti a molti qui. Inoltre, le tabelle sono uno-a-molti, quindi potrebbe essere oggetto di denormalizzazione. –

+0

Solo un appunto; in caso di confusione, la 'domanda risposta' sarebbe una colonna nella tabella product_questions – DRL

+0

@narcisradu m2m è chiaramente richiesto in questo caso; negozio può avere molti prodotti - un prodotto può essere in molti negozi: una domanda è su molti prodotti - un prodotto può avere molte domande. – DRL

1

Penso che il vostro disegno è a posto. Non aggiungerò lo ShopID alle domande del tavolo. Dovresti usare un join, se necessario.

BTW: utilizzare una relazione m: n tra prodotti e negozi e rimuovere ShopID per prodotti. Quindi puoi avere lo stesso prodotto nei vari negozi e anche le stesse domande per un prodotto.

saluti, Lars

+2

dovrebbe assolutamente evitare di usare una relazione molti-a-molti tra prodotti e negozi se i proprietari del negozio sono diversi. Immagina che ci sia lo stesso prodotto ma il prezzo differisce o qualsiasi altro attributo è diverso. –

+0

@narcisradu quindi avresti una tabella prodotti per ogni negozio? è molto semplice aggiungere parametri specifici del negozio alla tabella shop_products() nel mio esempio shop_products (..., sProduct_price, sProduct_stock) – DRL

+1

@DRL: Mentre tecnicamente ok il tuo M2M tra negozi e prodotti è probabilmente indesiderabile. Come proprietario di un negozio, vorrei che i miei dati fossero completamente separati dai dati di un altro proprietario del negozio anche se entrambi i gruppi di dati risiedono nello stesso database. E no, le tabelle dei prodotti separate per negozio non hanno senso, ma sì, vuoi una relazione 1-to-me tra negozio e prodotto. Ciò impedisce l'intreccio di dati tra negozi e semplifica notevolmente l'importazione e l'esportazione di dati di prodotto per un singolo negozio. Questo è importante, perché come proprietario di un negozio desidero impostare rapidamente e poter partire velocemente. –

2

Da un punto di vista progettuale, la memorizzazione di dati ridondanti non è necessario. Nel tuo caso potrebbe essere. Prova a fare alcuni test e se il tempo di interrogazione è migliorato a causa di questa ridondanza, allora dovresti procedere con la denormalizzazione.

Problemi correlati