Design ottimale del database per la relazione a 3 vie

1

Va bene, so che sembra complicato, ma tutte le relazioni sono, lemme, chiarire. Bene, ho tre entità nel mio database che sono legate l'una all'altra in una serie di relazioni, l'app è per ristoranti e le tabelle sono le seguenti:

Customers
Id
Name
Email
Packages
Id
Name
ImageUrl
Price
Description
Products (One package may have 1 to many products)
Products
Id
Name
ImageUrl
Price
Description
Orders
Id
CustomerId
Address

L'unica tabella in più menzionata è solo per chiarimenti, in quanto il cliente può effettuare un ordine. Ecco, ora le relazioni sono definite come segue:

  • Il cliente può effettuare più ordini, un ordine è associato a un solo cliente, uno a molti (questo è per chiarimenti)
  • Un pacchetto può contenere più prodotti, un prodotto può appartenere a più pacchetti (considerare pacchetti come offerte in un ristorante, come le offerte hanno gli stessi articoli / prodotti che il ristorante già offre), molti a molti
  • Un ordine può contenere più prodotti, un prodotto può avere più ordini, molti a molti
  • Un ordine può contenere più pacchetti, un pacchetto può avere più ordini, molti a molti

Gli ultimi tre sono i principali su cui dobbiamo concentrarci, ora la cosa è come progettare questo nel database. Come per molti a molti, utilizzeremo tabelle di riferimento o relazioni, come per es. nel caso di pacchetti e prodotti, è possibile creare una tabella package_products e questo è tutto bene, siamo pronti a portare il costo della query alla nuova tabella in cambio di una buona metodologia. E lo stesso deve essere fatto per la tabella ordini e prodotti, una nuova tabella order_products che soddisfa le loro esigenze molti-a-molti. Inoltre, lo stesso vale per le due entità, ordini e pacchetti, va tutto bene. Ma ora, dal lato delle query, dobbiamo ottimizzarlo, come già esistono le soluzioni, quella che ho menzionato, puoi avere qualcosa di simile, quello che voglio è qualcosa di meglio.

Se voglio, ad es. ottenere i dettagli di un ordine, che può avere molti pacchetti e prodotti allo stesso tempo, dovrà interrogare la tabella degli ordini, quindi la tabella di riferimento per gli ordini e i prodotti per ottenere singoli prodotti, quindi dovrà interrogare separatamente la tabella di riferimento per ordini e pacchetti per ottenere i pacchetti in esso. Detto questo, e al momento buono, ma se avete notato, i pacchetti sono fatti di prodotti, quindi in pratica gli ordini stanno memorizzando le informazioni per un gruppo di prodotti alcuni dei quali facevano parte di un pacco / pacchetto e l'altro , bene no. Mentre apriamo i pacchetti in un ordine, finiamo praticamente per ritrovare la stessa tabella di prodotto, una sorta di movimento posteriore del cerchio. Domande:

  • Anche questa tecnica è pessima? Ho iniziato a pensarlo così
  • Come posso evitare questo se è?
  • Come evitare infine il costo aggiuntivo della query, nella tabella del pacchetto ordini e così via?
  • È la tecnica che mette un ID di pacchetto in più nella tabella order_products male, se no che cosa sarebbe chiamata questa relazione ternaria ed è anche permessa?

Grazie in anticipo per leggere e rispondere con la grande virtù della pazienza.

    
posta user3950705 02.10.2014 - 08:54
fonte

2 risposte

1

Tre punti:

In primo luogo, è necessario utilizzare JOIN a proprio vantaggio, in modo da recuperare i dati uniti che si desidera con un solo viaggio nel database, anziché i viaggi ripetitivi nel database. Come ha giustamente osservato James Anderson, questo è ciò che sono i database relazionali.

Tuttavia, se stai solo imparando come utilizzare un database in SQL, l'utilizzo di un database di tua progettazione potrebbe farti seguire la strada sbagliata. Il database deve essere progettato bene per sfruttare tutta la potenza di JOIN e di altri due operatori relazionali, noti come restrittivi e in matematica relazionale. Le parole d'ordine SQL sono WHERE, DISTINCT e GROUP BY.

In secondo luogo, la relazione tra pacchetti e prodotti è il tuo caso base per le distinte materiali. Questo caso è stato ampiamente studiato in pratica negli ultimi quarant'anni. Non è necessario reinventare la ruota. Tuttavia, se si aggiunge la possibilità che i pacchetti possano essere composti da altri pacchetti, il problema BOM diventa ricorsivo. SQL non è costruito per la ricorsione, ma ci sono soluzioni alternative.

Se affronti la tecnica del set nested per progettare le gerarchie di contenimento, come BOM, riduci quella che sarebbe stata una query ricorsiva in una semplice query SQL che il server di database può decomporre in un semplice processo reiterativo per tu. Nested-set non è in definitiva complicato, ma qui c'è una curva di apprendimento.

In terzo luogo, la relazione tra dettagli dell'ordine e prodotti o pacchetti non è in realtà una relazione ternaria, nel modo in cui tale termine viene solitamente utilizzato. Ogni dettaglio dell'ordine fa riferimento a un ordine (il genitore) e a un prodotto o a un pacco. Questa o-situazione è la tipica situazione sottoclasse di classe (tipo-sottotipo), piuttosto che una vera relazione ternaria. Sfortunatamente, vanilla SQL non è buono per l'ereditarietà. È possibile utilizzare estensioni a SQL specifiche del proprio DBMS, se disponibili, oppure è possibile utilizzare una delle due tecniche, denominate "ereditarietà di tabelle singole" o "ereditarietà di tabelle di classi". Mi piace il modo in cui Fowler tratta questo argomento.

C'è molto da imparare qui. Sembri un programmatore intelligente, quindi dovresti essere in grado di impararlo velocemente. Non pensare che tu lo sappia già. Forse lo fai, forse non lo fai.

    
risposta data 02.10.2014 - 09:55
fonte
0

SQL ha una sintassi "JOIN" per fare ciò che vuoi.

Si tratta di database relazionali. Sono progettati per filtrare ("WHERE") e combinare ("FULL | OUTER | INNER JOIN") set di dati.

Qualsiasi RDBMS dovrebbe gestire i requisiti di partecipazione senza problemi in quanto sono ottimizzati per questo. In nessun caso dovresti aderire al codice del programma perché questo è orribilmente inefficiente.

    
risposta data 02.10.2014 - 09:21
fonte

Leggi altre domande sui tag