Domanda

Sto cercando di creare alcune funzionalità che mantiene una traccia di verifica di come i dati in un determinato modulo utente è stata modificata nel corso del tempo, con una verifica datato ai piedi di quella pagina. Ad esempio:

02/04/09 21:49 Nome passa da "Tom" a "Chris".

Lo sto facendo memorizzando i dati in esso è presente formato nella sessione e poi su Save verificando se vi siano differenze nei dati che vengono memorizzati. Se ci sono, sto memorizzando i dati come era prima l'ultima modifica in una tabella chiamata storia, e memorizzare i nuovi valori nella tabella utente corrente.

E 'questo l'approccio migliore da prendere?

È stato utile?

Soluzione

Un suggerimento; questo sarebbe relativamente facile da fare in un trigger del database. In tal caso, non avrebbe mai dovuto preoccuparsi se il codice in esecuzione l'aggiornamento si ricorda di aggiungere un record storico.

Altri suggerimenti

Non sono sicuro che ci sia un "approccio migliore", ci sono così tante variabili da prendere in considerazione, tra cui quanto in basso il percorso di sviluppo ci si trovi.

Essendo stato attraverso entrambe le soluzioni di controllo basati su codice e db-trigger, ho elencato alcuni commenti qui sotto; Spero che si può vedere dove sei ora a (in termini di sviluppo) potrebbe incidere su questi temi:

  • Se è necessario mappare l'utente che ha modificato i dati (che si fa normalmente) poi trigger db sarà necessario per ottenere queste informazioni in qualche modo. Non impossibile, ma più lavoro e diversi modi per affrontare questo (DB query di esecuzione, colonna utente comune in ogni tabella, ecc.)
  • Se si utilizza trigger db e si basano su righe coinvolte conteggio restituito dalle query, quindi la vostra verifica innesca bisogno di avere questo spento, o il vostro codice esistente modificato per tenere conto di loro.
  • IMHO db trigger offrono maggiore sicurezza, e di offrire un percorso più facile per controllare l'automazione, tuttavia essi non sono infallibili, come chiunque abbia accesso appropriato può disabilitare i trigger, modificare i dati e quindi permettere loro di nuovo. In altre parole, garantire i diritti di accesso di sicurezza db sono stretti.
  • Avere un unico tavolo per la storia non è un brutto modo di andare, anche se si avrà più lavoro da fare (e di dati da memorizzare) se si sta controllando la storia per più tabelle, soprattutto quando si tratta di ricostruire la pista di controllo. È inoltre necessario considerare le questioni di blocco se non ci sono molti tavoli cercando di scrivere ad una tabella di controllo.
  • Avere una tabella di cronologia di controllo per ogni tavolo è un'altra opzione. Hai solo bisogno di ogni colonna della tabella di controllo per essere annullabile, così come la data e l'ora di azione (inserimento / aggiornamento / eliminazione) e l'utente associato con l'azione memorizzazione.
  • Se si va con l'opzione singola tabella, a meno che non hai un sacco di tempo da spendere per questo, non si ottiene troppo di fantasia cercando di controllare solo su aggiornamenti o eliminazioni, anche se può essere tentati di evitare di inserti (poiché la maggior parte apps fanno più spesso di aggiornamenti o eliminazioni), ricostruire la storia di revisione prende un bel po 'di lavoro.
  • Se i server oi dati coprono più fusi orari, quindi prendere in considerazione utilizzando un tipo datetime appropriato per essere in grado di memorizzare e ricostruire la sequenza temporale, vale a dire negozio di audit data dell'evento in UTC, nonché tra cui compensato fuso orario.
  • Le tabelle di controllo possono ottenere enormi, in modo da avere una strategia se iniziano influire sulle prestazioni. Le opzioni includono il partizionamento delle tabelle su diversi dischi, archiviazione, ecc fondamentalmente pensare a questo ora e non quando diventa un problema:)

Sono sempre stato un fan di utilizzare una tabella invece di rompere in su in una tabella "attivo" e un tavolo "storia". Ho messo 4 colonne su queste tabelle, tutti i timestamp: creato, eliminato, inizio, fine. "Creato" e "cancellati" sono abbastanza auto-esplicativo. I timestamp "Start" e "fine" sono per quando il record è stato in realtà il record "attivo". Il record correntemente attivo avrebbe un tempo di "start" prima di now() e un NULL tempo "fine". Separando le "create" e "Start" tempi, è possibile pianificare i cambiamenti che si terrà in futuro.

Questo progetto, in contrasto con il design a due tavolo, consente di scrivere facilmente le query che opereranno automaticamente i dati corretti. Supponiamo che il vostro tavolo sta memorizzando l'aliquota d'imposta nel corso del tempo ... non si vuole avere tutte le vostre domande che utilizzano le aliquote fiscali nei loro calcoli hanno la complessità supplementare di decidere di cercare roba in una tabella di storia in cui l'elaborazione di vecchie fatture, per esempio ... si può solo guardare in alto l'aliquota fiscale in vigore al momento della fattura è stato creato in una query, a prescindere dal fatto che sia l'aliquota d'imposta in corso o meno.

Questa idea non è originariamente il mio (anche se ho fatto re-inventare l'idea di massima per conto mio prima di leggere su di esso) ... è possibile trovare una descrizione dettagliata di esso in questo linea libro .

Il coinvolgimento della sessione mi fa un po 'diffidenti (sei sicuro che stai gestire in modo corretto quando due utenti stanno lavorando sugli stessi dati nello stesso momento?), Ma in generale, sì, mantenendo un tavolo la storia è il diritto cosa.

Vorrei anche pensare a un trigger di database in inserimento o aggiornamento per registrare i dettagli di cambiamento (chi, quando, cosa, valore prima, valore dopo) ad una tabella di controllo separata. In questo modo si sa che anche se i dati è cambiato outide della vostra applicazione utilizzando direttamente il database, sarà ancora essere raccolto.

Si potrebbe anche voler fare qualcosa per rilevare se i dati sono cambiati outide della vostra applicazione, come ad esempio calcolare un hash o crc del record e conservarlo in un campo da qualche parte, quindi controllare quando la lettura dei dati.

Credo che la vostra proposta comporterebbe scrivere un sacco di codice / metadati per consentire il confronto di oggetti / record in modo da ottenere una verifica a livello aziendale.

In alternativa, un trigger del database non può dare una visione ad alta sufficiente livello di ciò che è accaduto. Questo può essere accettabile se si utilizza la verifica così raramente che lo sforzo di ricreare il senso di business è ok.

Questo sembra anche una buona applicazione per AOP (aspetti), dove è possibile utilizzare la riflessione sul modello di oggetti per fare uscire qualcosa di significativo senza richiedere un sacco di metadati.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top