Domanda

Ho una domanda relativa alle due colonne aggiuntive (timeCreated, timeLastUpdated) per ogni record che vediamo in molte soluzioni. La mia domanda: esiste un'alternativa migliore?

Scenario: hai un enorme DB (in termini di tabelle, non di record), quindi arriva il cliente e ti chiede di aggiungere " timestamping " all'80% dei tuoi tavoli.

Credo che ciò possa essere realizzato usando una tabella separata (TIMESTAMPS). Questa tabella avrebbe, oltre all'ovvia colonna timestamp, il nome della tabella e la chiave primaria per la tabella da aggiornare. (Suppongo qui che tu usi un int come chiave primaria per la maggior parte delle tue tabelle, ma il nome della tabella molto probabilmente dovrebbe essere una stringa).

Per immaginarlo supponiamo questo scenario di base. Vorremmo avere due tabelle:

PAGAMENTO: - (i tuoi soliti record)
TIMESTAMP: - {timestamp corrente} + { TABLE_UPDATED , id_of_entry_updated , timestamp_type }

Nota che in questo disegno non hai bisogno di quei due " extra " colonne nell'oggetto di pagamento nativo (che, tra l'altro, potrebbe passare attraverso la tua soluzione ORM) perché ora stai indicizzando TABLE_UPDATED e id_of_entry_updated . Inoltre, timestamp_type ti dirà se la voce è per l'inserimento (ad es. & Quot; 1 "), l'aggiornamento (ad es. & Quot; 2 ") e qualsiasi altra cosa che potresti voler aggiungere, come " cancellazione " ;.

Vorrei sapere cosa ne pensi di questo design. Sono molto interessato alle migliori pratiche, a ciò che funziona e scala nel tempo. Riferimenti, collegamenti, post di blog sono più che benvenuti. Conosco almeno un brevetto (in corso di registrazione) che tenta di risolvere questo problema, ma sembra che i dettagli non siano al momento pubblici.

Saluti, Eduardo

È stato utile?

Soluzione

Mentre ci sei, registra anche l'utente che ha apportato la modifica.

Il difetto con il design della tabella separata (oltre alle prestazioni di join evidenziate da altri) è che si presume che ogni abbia una colonna identità per la chiave. Questo non è sempre vero.

Se si utilizza SQL Server, la nuova versione 2008 supporta qualcosa che chiamano Modifica acquisizione dati che dovrebbe eliminare gran parte del dolore di cui stai parlando. Penso che anche Oracle possa avere qualcosa di simile.


Aggiornamento: apparentemente Oracle lo chiama come SQL Server. O meglio, SQL Server lo chiama la stessa cosa di Oracle, poiché l'implementazione di Oracle è arrivata per prima;)
http://www.oracle.com/technology/oramag/ oracle / 03-Nov / o63tech_bi.html

Altri suggerimenti

Ho usato un progetto in cui ogni tabella da controllare aveva due tabelle:

create table NAME (
  name_id int,
  first_name varchar
  last_name varchar
  -- any other table/column constraints
)

create table NAME_AUDIT (
  name_audit_id int
  name_id int
  first_name varchar
  last_name varchar
  update_type char(1) -- 'U', 'D', 'C'
  update_date datetime
  -- no table constraints really, outside of name_audit_id as PK
)

Viene creato un trigger di database che popola NAME_AUDIT ogni volta che viene fatto qualcosa su NAME . In questo modo si registra ogni singola modifica apportata alla tabella e quando. L'applicazione non ne è a conoscenza, poiché è gestita da un trigger di database.

Funziona abbastanza bene e non richiede alcuna modifica al codice dell'applicazione da implementare.

Penso di preferire aggiungere i timestamp alle singole tabelle. Partecipare alla tabella del timestamp su una chiave composita - una delle quali è una stringa - sarà più lento e se si dispone di una grande quantità di dati, alla fine sarà un vero problema.

Inoltre, molte volte quando guardi i timestamp, è quando stai eseguendo il debug di un problema nella tua applicazione e vorrai i dati proprio lì, piuttosto che dover sempre unirti contro l'altra tabella.

Il vantaggio del metodo che suggerisci è che ti dà la possibilità di aggiungere altri campi alla tabella TIMESTAMP, come tenere traccia dell'utente che ha apportato la modifica. Puoi anche tenere traccia delle modifiche ai campi sensibili, ad esempio chi ha rivalutato questo contratto?

La registrazione delle modifiche ai record in un file separato significa che puoi mostrare più modifiche a un record, come:

mm / gg / aa hh: mm: ss Aggiunto da XXX mm / gg / aa hh: mm: ss Campo PREZZO Modificato da XXX, mm / gg / aa hh: mm: ss Record cancellato da XXX

Uno svantaggio è il codice aggiuntivo che eseguirà gli inserimenti nella tabella TIMESTAMPS per riflettere le modifiche nelle tabelle principali.

Se si imposta il materiale timestamp per l'esecuzione dei trigger, è possibile registrare qualsiasi azione che può attivare un trigger (Leggi?). Inoltre potrebbero esserci alcuni vantaggi di blocco.

(Prendi tutto questo con un pizzico di sale, non sono un guru DBA o SQL)

Sì, mi piace quel design e lo uso con alcuni sistemi. Di solito, una variante di:

LogID  int
Action varchar(1)     -- ADDED (A)/UPDATED (U)/DELETED (D)
UserID varchar(20)    -- UserID of culprit :)
Timestamp datetime    -- Date/Time
TableName varchar(50) -- Table Name or Stored Procedure ran
UniqueID int          -- Unique ID of record acted upon
Notes varchar(1000)   -- Other notes Stored Procedure or Application may provide

Un incubo con il tuo design è che ogni singolo inserto, aggiornamento o eliminazione dovrebbe colpire quella tabella. Ciò può causare gravi problemi di prestazioni e blocco. È una cattiva idea generalizzare una tabella del genere (non solo per i timestamp). Sarebbe anche un incubo estrarre i dati.

Se il tuo codice si interromperà a livello di GUI aggiungendo campi che non desideri vengano visualizzati dall'utente, stai scrivendo erroneamente il codice nella tua GUI che dovrebbe specificare solo il numero minimo di colonne di cui hai bisogno e non selezionare mai *.

Penso che i join extra che dovrai eseguire per ottenere i Timestamp saranno un leggero colpo di performance e un dolore al collo. A parte questo, non vedo alcun problema.

Abbiamo fatto esattamente quello che hai fatto. È ottimo per il modello a oggetti e la possibilità di aggiungere nuovi timbri e tipi diversi di timbri al nostro modello con un codice minimo. Stavamo anche monitorando l'utente che ha apportato la modifica e molta della nostra logica era fortemente basata su questi francobolli. Si è svegliato molto bene.

Uno svantaggio è la segnalazione e / o la visualizzazione di molti timbri diversi sullo schermo. Se lo stai facendo nel modo in cui l'abbiamo fatto, ha causato molti join. Inoltre, i cambiamenti di back-end sono stati un dolore.

La nostra soluzione è mantenere una "Transazione" tabella, oltre alla nostra "Sessione" tavolo. Le istruzioni UPDATE, INSERT e DELETE sono tutte gestite tramite una "Transaction" oggetto e ciascuna di queste istruzioni SQL è memorizzata nella " Transaction " tabella una volta eseguita correttamente sul database. Questa " Transazione " la tabella ha altri campi come transazionetipo (I per INSERISCI, D per ELIMINA, U per AGGIORNAMENTO), transazioneDataTempo, ecc. e una chiave esterna "sessionId", che ci dice infine chi ha inviato l'istruzione. È anche possibile, attraverso alcuni codici, identificare chi ha fatto cosa e quando (Gus ha creato il record lunedì, Tim ha modificato il prezzo unitario martedì, Liz ha aggiunto uno sconto extra giovedì, ecc.)

I vantaggi di questa soluzione sono:

  1. sei in grado di dire " cosa chi e quando " ;, e mostrarlo ai tuoi utenti! (avrai bisogno di un po 'di codice per analizzare le istruzioni SQL)
  2. se i dati vengono replicati e la replica non riesce, è possibile ricostruire il database tramite questa tabella

I contro sono

  1. 100.000 aggiornamenti di dati al mese significano 100.000 record in Tbl_Transaction
  2. Infine, questa tabella tende ad essere il 99% del volume del database

La nostra scelta: tutti i record più vecchi di 90 giorni vengono automaticamente cancellati ogni mattina

Philippe,

Non semplicemente eliminare quelli più vecchi di 90 giorni, spostarli prima in un DB separato o scriverli in un file di testo, fare qualcosa per preservarli, semplicemente spostarli dal DB di produzione principale.

Se mai si arriva a questo, il più delle volte si tratta di "lui con la maggior parte della documentazione vince"!

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