Questo NON è facile.
Stai essenzialmente richiedendo un database temporale (che Christopher Date chiama Sixth Normal Form o 6NF).
Per essere 6NF, uno schema deve anche essere 5NF, e, in sostanza, per ogni dato, è necessario collegare un intervallo di tempo per il quale è applicabile il dato a quel valore. Quindi, in join, il join deve includere solo le righe che si trovano nell'intervallo di tempo considerato.
La modellazione temporale è difficile - è ciò che è il sesto indirizzo di forma normale - e non è ben supportata negli attuali RDBMS.
Il problema è la granularità. La sesta forma normale (a quanto ho capito) supporta la modellazione temporale rendendo ogni non chiave (non-chiave :, cioè, qualsiasi cosa "su" l'entità che può cambiare senza che l'entità perda la sua identità) una relazione separata. A questo, aggiungi un timestamp o un intervallo di tempo o un numero di versione. Rendere tutto un join risolve il problema della granularità, ma significa anche che le tue query saranno più complicate e lente. Richiede anche di capire tutte le chiavi e gli attributi non chiave; questo tende ad essere un grande sforzo.
In sostanza, ovunque si ha una relazione ("ted possiede il titolo azionario GM con id 789") si aggiunge un tempo: "ted possiede il titolo azionario GM con id 789 ora" in modo che si può dire contemporaneamente, "Fred possiede il certificato azionario GM con ID 789 dal 3 febbraio 2000 a ieri". Ovviamente queste relazioni sono molte-a-molti, (Ted può possedere più di un certificato ora, e anche più di uno nel corso della sua vita, e fred può avere in precedenza posseduto il jack del certificato proprio ora).
Quindi abbiamo una tabella di proprietari e una tabella di certificati azionari e una tabella molti-a-molti che mette in relazione proprietari e certificati con id. Alla tabella many-to-many, aggiungiamo un start_date e un end_date.
Ora, immagina che ogni stato/provincia/terra riscuota i dividendi sui certificati azionari, quindi a fini fiscali per registrare lo stato di residenza del proprietario del certificato azionario.
Dove risiede il proprietario può ovviamente cambiare in modo indipendente con la proprietà delle azioni; Ted può vivere in Nebraska, comprare 10 azioni, ottenere un dividendo che le tasse del Nebraska, trasferirsi in Nevada, vendere 5 azioni a Fred, comprare altre 10 azioni.
Ma per noi, è Ted può muoversi in Nebraska a un certo momento, acquistare 10 azioni a un certo momento, ottenere un dividendo a un certo momento, quali tasse Nebraska, passare a Neveda a un certo momento , vendere 5 azioni a fred a un certo momento, acquistare altre 10 azioni a un certo momento.
Abbiamo bisogno di tutto questo se vogliamo calcolare le tasse dovute in Nebraska e in Nevada, unendo gli intervalli di date corrispondenti/sovrapposti in person_stockcertificate e person_address. L'indirizzo di una persona non è più one-to-one, è uno-a-molti perché è l'indirizzo nell'intervallo di tempo.
Se ted acquista dieci azioni, modelliamo un evento di acquisto con un'unica data di acquisto o aggiungiamo una data_bought a ogni condivisione? Dipende dalla domanda a cui il modello deve rispondere.
SQL Server 2005 o 2008. Tuttavia, se c'è un altro RDBMS con una soluzione integrata per questo tipo di problema, sarei interessato a sentirlo. Thx – saille