Il miglior design per una tabella di database di log delle modifiche / controllo? [chiuso]


114

Ho bisogno di creare una tabella di database per memorizzare diversi log / controlli delle modifiche (quando qualcosa è stato aggiunto, eliminato, modificato, ecc.). Non ho bisogno di memorizzare informazioni particolarmente dettagliate, quindi stavo pensando qualcosa sulla falsariga di:

  • id (per evento)
  • utente che l'ha attivato
  • nome dell'evento
  • descrizione dell'evento
  • timestamp dell'evento

Mi manca qualcosa qui? Ovviamente posso continuare a migliorare il design, anche se non ho intenzione di renderlo complicato (creare altre tabelle per tipi di eventi o cose del genere è fuori questione poiché è una complicazione per le mie necessità).


Ho letto la tua risposta e sono sorpreso che nessuno parli di diritto. So che alcune leggi o documenti di buona pratica spiegano come DOBBIAMO implementare una tabella di audit (di sola lettura). Ma non ho più informazioni di queste. So solo che esiste. Sto pensando all'Audit trail in CFR 21 parte 11.
Bastien Vandamme

Risposte:


70

Nel progetto a cui sto lavorando, il registro di controllo è partito anche dal design molto minimalista, come quello che hai descritto:

event ID
event date/time
event type
user ID
description

L'idea era la stessa: mantenere le cose semplici.

Tuttavia, è diventato subito evidente che questo design minimalista non era sufficiente. L'audit tipico si riduceva a domande come questa:

Who the heck created/updated/deleted a record 
with ID=X in the table Foo and when?

Quindi, per poter rispondere rapidamente a tali domande (utilizzando SQL), abbiamo finito per avere due colonne aggiuntive nella tabella di audit

object type (or table name)
object ID

Questo è il momento in cui la progettazione del nostro registro di controllo si è davvero stabilizzata (da alcuni anni a questa parte).

Ovviamente, l'ultimo "miglioramento" funzionerebbe solo per le tabelle che avevano chiavi surrogate. Ma indovina un po? Tutte le nostre tabelle che meritano di essere verificate hanno questa chiave!


L'unico problema che ho avuto con questo progetto (un audit trail basato sulla "descrizione") è stato localizzare la lingua utilizzata in quel campo.
Sam Wilson,

@Sam Non vedo questo problema, se il messaggio è generato dal sistema, usa semplicemente una chiave qui per la stringa di traduzione;
JCM

4
@Hiru: Quando "mescoli" due o più concetti distinti in una colonna, il più delle volte si ritorcerà contro, prima o poi. Ad esempio, se "mischi" il tipo di evento e il tipo di oggetto, influirebbe su query come "mostrami i record per tutti gli oggetti del tipo dato" e "mostrami i record per tutti gli eventi di un determinato tipo" (le query sarebbero più complicato e molto probabilmente funzionerebbe molto più lentamente).
Yarik

3
Oltre a queste colonne, è possibile avere una colonna aggiuntiva per la descrizione strutturata / il payload dell'evento strutturato . Questa colonna conterrebbe i dettagli dell'evento (di qualsiasi complessità) in un formato leggibile dal computer, XML / JSON. Facile da serializzare, da interrogare (almeno in Postgres / MSSQL), su cui ragionare.
turdus-merula

1
@Benjamin: la risposta è nel modello di dominio (noto anche come modello di business). Se il modello consente la creazione simultanea di entità (ad esempio come parte di una transazione logica), non vedo alcun problema nell'avere più record di log con esattamente lo stesso timestamp. Ad esempio, se la creazione di un ordine di acquisto (come transazione) può includere la creazione di N articoli dell'ordine, tutti i record di registro 1 + N corrispondenti avrebbero lo stesso timestamp. L'analisi successiva di tale registro potrebbe trarne vantaggio, trattando questi record 1 + N non come indipendenti ma come elementi di una transazione logica. Spero che questo abbia un senso.
Yarik

24

Registriamo anche i valori vecchi e nuovi e la colonna da cui provengono, nonché la chiave primaria della tabella sottoposta a verifica in una tabella dei dettagli di verifica. Pensa a cosa ti serve la tabella di audit? Non solo vuoi sapere chi ha apportato una modifica e quando, ma quando si verifica una brutta modifica, vuoi un modo veloce per reinserire i dati.

Durante la progettazione, dovresti scrivere il codice per recuperare i dati. Quando hai bisogno di riprenderti, di solito è di fretta, meglio essere già preparati.


1
Questo è davvero buono Non capisco perché le persone ignorano gli ultimi post.
Maddy.Shik

3
Il sourcing degli eventi è un approccio alternativo per fornire funzionalità di rollback mantenendo la cronologia.
Sam

23

Ci sono molte altre cose che potresti voler controllare, come nomi di tabelle / colonne, computer / applicazioni da cui è stato effettuato un aggiornamento e altro.

Ora, questo dipende da quanto è realmente necessario l'auditing dettagliato ea quale livello.

Abbiamo iniziato a creare la nostra soluzione di audit basata su trigger e volevamo controllare tutto e avere anche un'opzione di ripristino a portata di mano. Questo si è rivelato troppo complesso, quindi abbiamo finito per eseguire il reverse engineering dello strumento di terze parti basato su trigger ApexSQL Audit per creare la nostra soluzione personalizzata.

Suggerimenti:

  • Includi valori prima / dopo

  • Includi 3-4 colonne per memorizzare la chiave primaria (nel caso sia una chiave composta)

  • Memorizza i dati al di fuori del database principale come già suggerito da Robert

  • Dedica una discreta quantità di tempo alla preparazione dei rapporti, specialmente quelli di cui potresti aver bisogno per il recupero

  • Pianificare l'archiviazione del nome dell'host / dell'applicazione: potrebbe essere molto utile per tenere traccia delle attività sospette


2
Perché dovresti decodificarlo invece di acquistarlo?
Jowen

1
più controllo sul prodotto
Tebe

1
Spero non ti abbiano fatto causa.
Sorter

9

Ci sono molte risposte interessanti qui e in domande simili. Le uniche cose che posso aggiungere dall'esperienza personale sono:

  1. Metti la tua tabella di controllo in un altro database. Idealmente, vuoi la separazione dai dati originali. Se è necessario ripristinare il database, in realtà non si desidera ripristinare la traccia di controllo.

  2. Denormalizza il più ragionevolmente possibile. Si desidera che la tabella abbia il minor numero di dipendenze possibile dai dati originali. La tabella di audit dovrebbe essere semplice e velocissima da cui recuperare i dati. Nessuna operazione di join o ricerca su altre tabelle per accedere ai dati.


8
I dati non normalizzati sarebbero davvero più veloci da leggere rispetto ai dati normalizzati con indici appropriati? (Tutta la duplicazione non risulterebbe nella lettura di più dati dall'HDD?)
Sam

4

Cosa abbiamo nella nostra tabella: -

Primary Key
Event type (e.g. "UPDATED", "APPROVED")
Description ("Frisbar was added to blong")
User Id
User Id of second authoriser
Amount
Date/time
Generic Id
Table Name

L'id generico punta a una riga nella tabella che è stata aggiornata e il nome della tabella è il nome di quella tabella come stringa. Non è un buon design DB, ma molto utilizzabile. Tutte le nostre tabelle hanno una singola colonna chiave surrogata, quindi funziona bene.


2
Cosa rappresenta "importo"?
turdus-merula

È un'applicazione finanziaria, quindi è il valore in dollari della cosa autorizzata, ecc.
WW.

4

In generale, l'audit personalizzato (creazione di varie tabelle) è una cattiva opzione. I trigger di database / tabelle possono essere disabilitati per saltare alcune attività di registro. Le tabelle di controllo personalizzate possono essere manomesse. Possono verificarsi eccezioni che interrompono l'applicazione. Per non parlare delle difficoltà nel progettare una soluzione robusta. Finora vedo casi molto semplici in questa discussione. È necessaria una separazione completa dal database corrente e da eventuali utenti privilegiati (DBA, Sviluppatori). Tutti gli RDBMS tradizionali forniscono funzionalità di controllo che nemmeno i DBA sono in grado di disabilitare, manomettere in segreto. Pertanto, la capacità di controllo fornita dal fornitore RDBMS deve essere la prima opzione. Un'altra opzione potrebbe essere un lettore di log delle transazioni di terze parti o un lettore di log personalizzato che inserisce le informazioni scomposte nel sistema di messaggistica che finisce in alcune forme di Audit Data Warehouse o gestore di eventi in tempo reale. In sintesi: Solution Architect / "Hands on Data Architect" deve coinvolgere la destinazione di un tale sistema in base ai requisiti. Di solito è roba troppo seria da consegnare a uno sviluppatore per una soluzione.


3

Ci sono molti modi per farlo. Il mio modo preferito è:

  1. Aggiungi un mod_usercampo alla tua tabella di origine (quella che desideri registrare).

  2. Crea una tabella di registro che contiene i campi che desideri registrare, oltre a un campo log_datetimee seq_num. seq_numè la chiave primaria.

  3. Crea un trigger sulla tabella di origine che inserisce il record corrente nella tabella di registro ogni volta che viene modificato un campo monitorato.

Ora hai un record di ogni cambiamento e chi lo ha fatto.


Allora ... cosa dovrebbe fare il campo mod_user?
conny

1
Dirti chi ha apportato il cambiamento. L'aggiornamento del codice dovrebbe includere qualcosa per impostare quel campo sull'utente corrente.
JosephStyons

E le eliminazioni, quindi? Se elimini una riga, come gestisci il valore per la colonna mod_user?
Kenn Cal

I trigger @KennCal possono utilizzare tabelle virtuali, puoi vedere i dati dopo e prima all'interno dello stesso trigger. Non importa l'operazione. stackoverflow.com/questions/6282618/…
Renan Cavalieri,

2
@KennCal Hai ragione, il trigger di eliminazione dovrà memorizzare tali informazioni per te. Il diavolo è però nei dettagli: se stai usando l'autenticazione SQL, il trigger può semplicemente essere eseguito [seleziona CURRENT_USER]. Se si tratta di un'applicazione client, il codice client deve annunciare chi è. Se si tratta di una chiamata API, l'utente che elimina deve essere un parametro obbligatorio per la chiamata.
JosephStyons

1

Secondo il principio di separazione:

  1. Le tabelle dei dati di controllo devono essere separate dal database principale. Poiché i database di audit possono contenere molti dati storici, dal punto di vista dell'utilizzo della memoria ha senso tenerli separati.

  2. Non utilizzare trigger per controllare l'intero database, perché ti ritroverai con un pasticcio di database diversi da supportare. Dovrai scriverne uno per DB2, SQLServer, Mysql, ecc.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.