Cascading "Cancellato" record che non sono realmente cancellati

8

Sto solo cercando di ottenere alcune idee su ciò che le persone fanno per questo scenario. Abbiamo un database di sistema (SQL Server 2008 R2) con tabelle e ogni tabella ha un campo che possiamo chiamare "Eliminato". È fondamentalmente un campo bit se è 1 il record è cancellato, se è uno 0 non viene cancellato. Il campo non è annullabile e il suo valore predefinito è ovviamente 0.

Non possiamo permettere reali cancellazioni al database, quindi per aggirare questo impostiamo un campo bit (Eliminato) su true. Nella nostra applicazione ci ritroviamo con una query simile a questa:

SELECT blah FROM MyTable WHERE .. AND Deleted=0

Fondamentalmente filtriamo i record in modo da ottenere solo righe non cancellate. Il nostro problema sono i record correlati che devono essere sovrapposti. Cosa preferiscono le persone, dovremmo farlo nel codice lato server in modo che quando cancelli un record cancelli (imposta il campo bit cancellato su true) per tutti i record correlati? O dovrebbe essere un trigger che deve controllare questo campo e imposta il campo di bit per tutti i record correlati su 1?

O siamo completamente sulla strada sbagliata?

    
posta JonH 09.01.2014 - 17:35
fonte

3 risposte

2

Non c'è una buona soluzione qui. I database offrono un'eliminazione a cascata speciale ed efficiente tramite chiavi esterne, ma se, come dici tu, l'eliminazione effettiva non è un'opzione, non puoi trarre vantaggio da quella cascata nativa.

A seconda che le eliminazioni siano un evento comune o raro, sarà più efficiente emulare il collegamento in cascata immediatamente (tramite query o trigger aggiuntivi) quando si elimina pseudo qualcosa o semplicemente per recuperare sempre tutto dal DB e filtrare sul flag di cancellazione nella business logic.

Personalmente, ho sempre usato una terza opzione: tutti i record sussidiari sono accessibili solo dal record principale, cosa che non succede mai se quella è stata cancellata, quindi non devi fare nulla! Ovviamente questo funziona solo se il tuo modello dati è un albero rigoroso (i commenti vengono recuperati solo quando si visualizza il prodotto a cui si applicano, i privilegi dell'utente vengono recuperati solo quando si amministrano gli utenti a cui appartengono, ecc.) Piuttosto che un web (dove è possibile eseguire una query tutti i commenti o tutti i record di privilegi indifferentemente), ma trovo che questo possa essere fatto funzionare per sorprendentemente molti scenari.

    
risposta data 09.01.2014 - 20:54
fonte
5

L'ho già fatto con le tabelle di controllo in cui ogni modifica a un database viene scritta su una tabella di mirror di controllo (Insert / Update / Delete) e gli elementi reali effettivi vengono eliminati in modo a cascata.

Le tabelle mirror sono identiche alla tabella reale con l'aggiunta di 3 colonne, "ChangeType", "User", "Date".

Questo ha il duplice vantaggio di poter cancellare i dati correttamente, ma anche di ricreare lo stato del database in qualsiasi momento e la cronologia completa di qualsiasi oggetto da documentare.

Aggiungerò questo per le eliminazioni a cascata, in genere preferisco le eliminazioni a cascata sul client - il server non dovrebbe cercare di essere troppo intelligente a questo proposito, se un utente elimina una società e ha problemi associati - l'azione elimina la società dovrebbe anche cancellare tutti i record corrispondenti.

Si trattava di un sistema di gestione finanziaria per una delle principali banche di investimento, pertanto l'auditabilità era una caratteristica critica.

    
risposta data 09.01.2014 - 18:17
fonte
1

Esegui esplicitamente l'istruzione delete / undelete. Ci sono probabilmente anche diversi scenari in cui non vuoi sovrapporre l'eliminazione.

> Update table1 set deleted=@flag where...
> Update table2 set deleted=@flag where...

Ad esempio; considera una persona con più indirizzi.

Cancellare la persona, basta impostare Elimina bandiera di persona. Non è necessario collegare a cascata l'eliminazione agli indirizzi, perché quando ripristiniamo, vogliamo che tali indirizzi vengano restituiti.

Diciamo che la persona si è trasferita, quindi vorremmo aggiornare il flag di cancellazione solo sul vecchio indirizzo, lasciando solo gli altri indirizzi e la persona. Quindi, la cascata potrebbe non essere sempre richiesta e dipenderebbe dallo scenario.

Quindi, penso che tu debba essere esplicito in base a come è impostato il tuo modello e a cosa stai eliminando.

    
risposta data 09.01.2014 - 22:44
fonte

Leggi altre domande sui tag