Domanda

Stiamo lavorando a un progetto al momento e dobbiamo implementare l'eliminazione temporanea per la maggior parte degli utenti (ruoli utente).Abbiamo deciso di aggiungere un campo "is_deleted='0'" su ciascuna tabella nel database e di impostarlo su "1" se particolari ruoli utente premono un pulsante di eliminazione su un record specifico.

Per la manutenzione futura ora, ogni query SELECT dovrà garantire che non includa record dove is_deleted='1'.

Esiste una soluzione migliore per implementare l'eliminazione temporanea?

Aggiornamento:Dovrei anche notare che disponiamo di un database di controllo che tiene traccia delle modifiche (campo, vecchio valore, nuovo valore, ora, utente, ip) a tutte le tabelle/campi all'interno del database dell'applicazione.

È stato utile?

Soluzione

Potresti eseguire tutte le tue query su una vista che contiene il file WHERE IS_DELETED='0' clausola.

Altri suggerimenti

Io propenderei per il "modo Rails" con a deleted_at colonna che contiene il data/ora in cui è avvenuta la cancellazione.Quindi riceverai alcuni metadati gratuiti sulla cancellazione.Per il tuo SELECT ottieni solo righe WHERE deleted_at IS NULL

Avendo is_deleted colonna è un approccio ragionevolmente buono.Se è in Oracle, per aumentare ulteriormente le prestazioni consiglierei di partizionare la tabella creando una partizione elenco su is_deleted colonna.Quindi le righe cancellate e non cancellate saranno fisicamente in partizioni diverse, anche se per te sarà trasparente.

Di conseguenza, se digiti una query simile

SELECT * FROM table_name WHERE is_deleted = 1

quindi Oracle eseguirà l'eliminazione della partizione e esaminerà solo la partizione appropriata.Internamente una partizione è una tabella diversa, ma è trasparente per te come utente:sarai in grado di selezionare l'intera tabella, indipendentemente dal fatto che sia partizionata o meno.Ma Oracle sarà in grado di interrogare SOLO la partizione di cui ha bisogno.Ad esempio, supponiamo che tu abbia 1000 righe con is_deleted = 0 e 100000 righe con is_deleted = 1, e partizioni la tabella is_deleted.Ora se includi condizione

WHERE ... AND IS_DELETED=0

quindi Oracle eseguirà la scansione SOLO della partizione con 1000 righe.Se la tabella non fosse partizionata, dovrebbe scansionare 101000 righe (entrambe le partizioni).

se la tabella è grande e le prestazioni sono un problema, puoi sempre spostare i record "eliminati" in un'altra tabella, che contiene informazioni aggiuntive come l'ora dell'eliminazione, chi ha eliminato il record, ecc.

in questo modo non devi aggiungere un'altra colonna alla tabella principale

La risposta migliore, purtroppo, dipende da cosa stai cercando di ottenere con le eliminazioni soft e dal database in cui le stai implementando.

In SQL Server, la soluzione migliore sarebbe utilizzare una colonna delete_on/deleted_at con un tipo SMALLDATETIME o DATETIME (a seconda della granularità necessaria) e rendere tale colonna nullable.In SQL Server, i dati dell'intestazione della riga contengono una maschera di bit NULL per ciascuna colonna nella tabella, quindi è leggermente più veloce eseguire IS NULL o IS NOT NULL piuttosto che controllare il valore archiviato in una colonna.

Se disponi di un grande volume di dati, ti consigliamo di esaminare la partizione dei dati, tramite il database stesso o tramite due tabelle separate (ad es.Prodotti e Storia del prodotto) o tramite una vista indicizzata.

In genere evito i campi flag come is_deleted, is_archive, ecc. perché hanno solo un significato.Un campo nullable delete_at, archived_at fornisce un ulteriore livello di significato a te stesso e a chiunque erediti la tua applicazione.Ed evito come la peste i campi della maschera di bit poiché richiedono una comprensione di come è stata costruita la maschera di bit per coglierne qualsiasi significato.

Dipende dalle informazioni di cui hai bisogno e dai flussi di lavoro che desideri supportare.

Vuoi essere in grado di:

  • sapere quali informazioni c'erano (prima che fossero cancellate)?
  • sai quando è stato cancellato?
  • sai chi l'ha cancellato?
  • sapere in quale veste agivano quando l'hanno cancellato?
  • essere in grado di ripristinare l'eliminazione del record?
  • essere in grado di dire quando non è stato cancellato?
  • eccetera.

Se il record è stato cancellato e ripristinato quattro volte, è sufficiente sapere che al momento è in uno stato non cancellato o vuoi essere in grado di dire cosa è successo nel frattempo (incluse eventuali modifiche tra successive modifiche? eliminazioni!)?

Fare attenzione ai record eliminati temporaneamente che causano violazioni dei vincoli di unicità.Se il tuo DB ha colonne con vincoli univoci, fai attenzione che i precedenti record eliminati temporaneamente non ti impediscano di ricreare il record.

Pensa al ciclo:

  1. crea utente (login=JOE)
  2. eliminazione temporanea (imposta la colonna eliminata su un valore diverso da null.)
  3. (ri) creare utente (login=JOE).ERRORE.LOGIN=JOE è già occupato

La seconda creazione comporta una violazione del vincolo poiché login=JOE è già nella riga eliminata temporaneamente.

Alcune tecniche:1.Sposta il record eliminato in una nuova tabella.2.Crea il tuo vincolo di unicità nella colonna timestamp login e delete_at

La mia opinione è +1 per passare a una nuova tabella.Ci vuole molta disciplina per mantenere * e delete_at = null * in tutte le tue domande (per tutti i tuoi sviluppatori)

Avrai sicuramente prestazioni migliori se sposti i dati eliminati in un'altra tabella come ha detto Jim, oltre a registrare quando sono stati eliminati, perché e da chi.

Aggiunta where deleted=0 a tutte le tue query le rallenterà in modo significativo e ostacolerà l'utilizzo di qualsiasi indice che potresti avere sul tavolo.Evita di avere "flag" nelle tue tabelle quando possibile.

Qualcosa che utilizzo sui progetti è uno statusind tinyint non null colonna predefinita 0 usando lo statusind come maschera bit mi consente di eseguire la gestione dei dati (elimina, archivio, replicare, ripristinare, ecc.).Usandolo nelle visualizzazioni posso quindi eseguire la distribuzione, la pubblicazione, ecc. dei dati per le applicazioni che li utilizzano.Se le prestazioni sono un problema per quanto riguarda le visualizzazioni, utilizzare piccole tabelle dei fatti per supportare queste informazioni, eliminando il fatto, eliminando la relazione e consentendo eliminazioni richiamate.

Si adatta bene ed è incentrato sui dati mantenendo l'impronta dei dati piuttosto piccola: chiave per 350 GB+ dbs con preoccupazioni in tempo reale.L'utilizzo di alternative, tabelle e trigger comporta un sovraccarico che, a seconda delle necessità, potrebbe funzionare o meno per te.

Gli audit relativi a SOX potrebbero richiedere più di un campo per aiutare nel tuo caso, ma questo può aiutare.Godere

non menzioni quale prodotto, ma SQL Server 2008 e postgresql (e altri ne sono sicuro) ti consentono di creare indici filtrati, in modo da poter creare un indice di copertura dove is_deleted=0, mitigando alcuni degli aspetti negativi di questo particolare approccio .

Preferisco mantenere una colonna di stato, quindi posso usarla per diverse configurazioni, ad es.pubblicato, privato, eliminato, necessita di approvazione...

utilizzare una vista, funzione o procedura che controlli is_deleted=0, ovveronon selezionare direttamente sulla tabella nel caso in cui la tabella debba essere modificata in seguito per altri motivi

e indicizzare la colonna is_deleted per le tabelle più grandi

poiché disponi già di una traccia di controllo, tenere traccia della data di eliminazione è ridondante

Crea un altro schema e concedi tutto al tuo schema dati.Implementa VPD sul tuo nuovo schema in modo che a ogni query venga aggiunto solo il predicato che consente la selezione della riga non eliminata.http://download.oracle.com/docs/cd/E11882_01/server.112/e16508/cmntopc.htm#CNCPT62345

@AdditionalCriteria("questo.status <> 'eliminato'")

mettilo sopra il tuo @entity

http://wiki.eclipse.org/EclipseLink/Examples/JPA/SoftDelete

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