Domanda di modellazione del database

1

Ho un dubbio durante la creazione di un DB, e vorrei sapere se ci sono argomenti oggettivi che potrebbero aiutarmi a prendere una decisione migliore.

Caso

Un progetto che può avere diverse revisioni, quindi ho creato l'entità Project e Project_Rev . Ogni revisione ha delle posizioni, quindi ho creato l'entità Position . Ogni posizione ha elementi, quindi ho creato l'entità Element . Fino a questo punto tutto è super-normale, da Project a Element entità per entità, è una relazione uno-a-molti, è possibile vedere nel grafico sottostante:

Ilproblemaèilseguente:%incrementodiProject_ReveincrementodiElements,manonesisteun'associazionelogica!Potreiavere:

Project1_Rev1->Position1->Element1_Rev1,Element2_Rev1Project1_Rev2->Position1->Element1_Rev4,Element2_Rev2Project1_Rev3->Position1->Element1_Rev5,Element2_Rev2Project1_Rev4->Position1->Element1_Rev5,Element2_Rev10

Perquestomotivo,hopensatoinduesoluzioni:

Soluzione1

PerconnettereProject_RevconElement,comel'immaginequisotto:

Questasoluzionefunziona,manonsembraquellagiustaperchéc'èridondanza,lostessoelementosaràreferenziatoduevolteneldatabaseperlostessoscopo!

Soluzione2

HopensatodicreareunatabelladiterradimezzoperProject_Rev,Position,Element,doveperognicombinazioneProject_RevePositionc'èunListdiElements.Comepuoivederenell'immaginequisotto:

L'immaginequisopranonècorretta,laseguenteè:

Questosembrapiùcorrettoperme,maacausadelledueconnessioniuno-a-uno"assaggia" come una vista per me! Tuttavia sembra più corretto, non c'è ridondanza come nella soluzione 1 di cui sopra!

Qual è il tuo consiglio al riguardo, dovrei usare la soluzione 1, la soluzione 2 o un'altra che non sto menzionando?

    
posta f4d0 10.12.2017 - 17:01
fonte

2 risposte

1

Soluzione 1 ha il vantaggio di riflettere perfettamente uno schema di versioning flessibile. Supponi di creare una nuova revisione del progetto:

  • potresti riorganizzare le posizioni (suddividendo una posizione precedente in due posizioni secondarie o due posizioni di gruppo in una posizione comune).
  • potresti aggiornare gli attributi di posizione (dopotutto è una nuova revisione, quindi le informazioni potrebbero essere cambiate).
  • puoi aggiungere o rimuovere elementi
  • puoi cambiare elementi (ad esempio diverse stime del carico di lavoro per gli elementi)

Ovviamente lo svantaggio è che gli elementi o le posizioni invariate sono semplicemente duplicati. Questo è il costo della flessibilità e della semplicità.

Se si desidera evitare la ridondanza, è necessario un alogritmo che funzioni con delta: solo gli elementi modificati vengono creati nella revisione. Ma poi avresti bisogno di un sofisticato algoritmo per leggere la cronologia e mettere insieme i pezzi.

Soluzione 2 sembra incoerente. Le relazioni uno a uno tra Project_Rev e Project_Rev_Position_Element e poi Project_Rev_Position_Element e Position indicano che esiste una sola posizione per revisione. È davvero quello che vuoi?

Soluzione aggiuntiva: se gli elementi sono potenzialmente condivisi tra più progetti, puoi optare per una relazione molti a molti. Il many-to-many richiede una tabella intermedia Element_in_Position:

 Project -< Project_Rev -< Position -< Element_in_Position >- Element

Con questa alternativa, due diverse revisioni potrebbero condividere gli stessi elementi se questi sono invariati, anche se sono messi in una posizione diversa. Se risulta che Element deve essere rivisto in una revisione, allora dovresti creare un clone e cambiare il clone.

Il vantaggio è che eviti la ridondanza di Element (potresti comunque averlo per Position ) e avere un controllo delle versioni completamente flessibile. L'unico problema è quando Element viene modificata: nel codice hai il codice per identificare l'intento dell'utente: cambiare gli attributi invarianti che devono essere condivisi tra tutte le versioni? cambia gli attributi specifici di una revisione specifica di un elemento che non è condiviso con altre revisioni? Oppure clonare un elemento condiviso in modo che le modifiche agli attributi possano essere limitate a una sola revisione.

    
risposta data 10.12.2017 - 21:46
fonte
0

Le immagini della soluzione 1 e della soluzione 2 nella domanda non sono corrette, perché, e menzionate nelle combinazioni di esempi nella domanda, ProjectRev e Position sono anche una connessione molti-a-molti.

Combinazioni:

Project1_Rev1 -> Position1 -> Element1_Rev1, Element2_Rev1
Project1_Rev2 -> Position1 -> Element1_Rev4, Element2_Rev2
Project1_Rev3 -> Position1 -> Element1_Rev5, Element2_Rev2
Project1_Rev4 -> Position1 -> Element1_Rev5, Element2_Rev10

Dopo un sacco di tempo a pensarci, la soluzione che ho trovato è la seguente:

Fondamentalmente, per ogni combinazione di entità ProjectRev e Position, avrò una lista di elementi. Con il citato, posso creare tutte le combinazioni necessarie e tenere traccia di tutte le cronologie delle combinazioni.

    
risposta data 11.12.2017 - 02:31
fonte