Prefazione: L'altro giorno stavo pensando a una nuova struttura di database per una nuova applicazione e mi sono reso conto che avevamo bisogno di un modo per archiviare i dati storici in modo efficiente. Volevo qualcun altro a dare un'occhiata e vedere se ci sono problemi con questa struttura. Mi rendo conto che questo metodo di memorizzazione dei dati potrebbe benissimo essere stato inventato prima (ne sono quasi certo) ma non ho idea se abbia un nome e alcune ricerche su google che ho provato non abbiano dato alcun risultato.Struttura del database per la memorizzazione dei dati storici
Problema: Diciamo che avete una tabella per gli ordini e gli ordini sono relativi a una tabella clienti per il cliente che ha effettuato l'ordine. In un normale struttura del database si potrebbe aspettare qualcosa di simile:
orders
------
orderID
customerID
customers
---------
customerID
address
address2
city
state
zip
piuttosto semplice, orderID ha una chiave esterna di customerID che è la chiave primaria della tabella cliente. Ma se dovessimo andare ed eseguire un report sulla tabella degli ordini, entreremo nella tabella dei clienti nella tabella degli ordini, che restituirà il record corrente per quell'ID cliente. Cosa succede se al momento dell'ordine, l'indirizzo del cliente era diverso ed è stato successivamente modificato. Ora il nostro ordine non riflette più la storia di quell'indirizzo del cliente, al momento dell'ordine. Fondamentalmente, cambiando il record del cliente, abbiamo appena cambiato tutta la cronologia per quel cliente.
Ora ci sono diversi modi per aggirare questo, uno dei quali sarebbe quello di copiare il record quando è stato creato un ordine. Quello che mi è venuto in mente è quello che penso sarebbe un modo più semplice per farlo, che è forse un po 'più elegante, e ha il vantaggio aggiuntivo di registrare ogni volta che viene apportata una modifica.
Che cosa succede se ho fatto una struttura come questa, invece:
orders
------
orderID
customerID
customerHistoryID
customers
---------
customerID
customerHistoryID
customerHistory
--------
customerHistoryID
customerID
address
address2
city
state
zip
updatedBy
updatedOn
ti prego di perdonare la formattazione, ma penso che si può vedere l'idea. Fondamentalmente, l'idea è che ogni volta che un cliente viene modificato, inserito o aggiornato, il customerHistoryID viene incrementato e la tabella dei clienti viene aggiornata con l'ultimo customerHistoryID. La tabella degli ordini ora non punta solo al customerID (che consente di vedere tutte le revisioni del record del cliente), ma anche al customerHistoryID, che indica una specifica revisione del record. Ora l'ordine riflette lo stato dei dati al momento della creazione dell'ordine.
Aggiungendo una colonna aggiornata e aggiornata alla tabella customerHistory, è anche possibile visualizzare un "registro di controllo" dei dati, in modo da poter vedere chi ha apportato le modifiche e quando.
Uno svantaggio potenziale potrebbe essere le eliminazioni, ma non mi preoccupo molto di questo per questo bisogno visto che nulla dovrebbe mai essere cancellato. Ma anche in questo caso, lo stesso effetto si può ottenere usando un activeFlag o qualcosa del genere a seconda del dominio dei dati.
Il mio pensiero è che tutti i tavoli utilizzino questa struttura. Ogni volta che vengono recuperati dati storici, questi verranno uniti alla tabella della cronologia utilizzando customerHistoryID per mostrare lo stato dei dati per quel particolare ordine.
Il recupero di un elenco di clienti è semplice, basta unirsi alla tabella clienti sul clienteHistoryID.
Qualcuno può riscontrare problemi con questo approccio, sia dal punto di vista del design, sia in termini di prestazioni, perché questo è negativo. Ricorda, non importa cosa faccio Devo assicurarmi che i dati storici siano conservati in modo che i successivi aggiornamenti dei record non cambino la cronologia. C'è un modo migliore? È un'idea nota che ha un nome o una documentazione su di esso?
Grazie per qualsiasi aiuto.
Aggiornamento: Questo è un esempio molto semplice di ciò che avrò davvero. La mia vera applicazione avrà "ordini" con diverse chiavi esterne ad altre tabelle. Informazioni sulla posizione di origine/destinazione, informazioni sui clienti, informazioni sulla struttura, informazioni sugli utenti, ecc. È stato suggerito un paio di volte di poter copiare le informazioni nel record dell'ordine in quel punto, e l'ho visto fare in questo modo molte volte, ma ciò comporterebbe un record con centinaia di colonne, che in questo caso non è realmente fattibile.
Quindi, in pratica quello che stai dicendo è questo: "Ho troppe colonne nella tabella ordine Perciò mi piacerebbe. per inserire l'indirizzo dell'ordine nella tabella clienti. Per supportarlo, vorrei compromettere i dati del cliente con uno schema di tracciamento cronologico complesso. " Mi sembra una cattiva idea. –
No ... niente affatto. Quello che sto dicendo è che devo essere in grado di tenere traccia degli indirizzi, quando cambiano, ed essere in grado di legare un ordine a uno stato specifico (revisione) di un indirizzo. Gli ordini potrebbero non essere l'unica tabella che lega ad un indirizzo, per non parlare vogliamo sapere quando e chi ha cambiato un indirizzo. –
BTW non presume mai che nulla verrà eliminato. Pianificare le eliminazioni che si verificheranno inevitabilmente o creare un trigger che non consenta le eliminazioni. – HLGEM