2008-09-19 12 views
35

È necessario memorizzare le modifiche immesse dall'utente in una determinata tabella, ma non mostrare tali modifiche finché non sono state visualizzate e approvate da un utente amministrativo. Mentre tali modifiche sono ancora in sospeso, visualizzerei comunque la versione precedente dei dati. Quale sarebbe il modo migliore di conservare queste modifiche in attesa di approvazione?Qual è il modo migliore per memorizzare le modifiche ai record del database che richiedono l'approvazione prima di essere visibili?

Ho pensato a diversi modi, ma non riesco a capire quale sia il metodo migliore. Questa è un'app web molto piccola. Un modo sarebbe di avere una tabella PendingChanges che imita lo schema dell'altro tavolo, e quindi una volta approvata la modifica, potrei aggiornare la tabella reale con le informazioni. Un altro approccio sarebbe quello di eseguire una sorta di controllo delle versioni dei record in cui memorizzo più versioni dei dati nella tabella e quindi estrarre sempre il record con il numero di versione più alto contrassegnato come approvato. Ciò limiterebbe il numero di tabelle aggiuntive (ho bisogno di farlo per più tabelle), ma mi richiederebbe di eseguire un'ulteriore elaborazione ogni volta che estraggo un set di record per assicurarmi di ottenere quelli giusti.

Eventuali esperienze personali con questi metodi o altri che potrebbero essere buoni?

Aggiornamento: Giusto per chiarire, in questa particolare situazione non mi interessa tanto nei dati storici. Ho solo bisogno di un modo per approvare eventuali modifiche apportate da un utente prima che vengano pubblicate sul sito. Quindi, un utente modificherà il proprio "profilo" e quindi un amministratore esaminerà tale modifica e la approverà. Una volta approvato, questo diventerà il valore visualizzato e la vecchia versione non dovrà essere conservata.

Qualcuno ha provato la soluzione qui sotto in cui si memorizzano le modifiche in sospeso da qualsiasi tabella che deve tracciarle come XML in una tabella PendingChanges speciale? Ogni record avrebbe una colonna che diceva a quale tabella erano destinate le modifiche, una colonna che forse memorizzava l'id del record che sarebbe stato modificato (null se si trattava di un nuovo record), una colonna datetime da memorizzare al momento della modifica, e una colonna per memorizzare l'xml del record modificato (potrebbe forse serializzare il mio oggetto dati). Poiché non ho bisogno di cronologia, dopo che è stata approvata una modifica, la tabella reale verrebbe aggiornata e il record PendingChange potrebbe essere eliminato.

Qualche idea su questo metodo?

+1

Vuoi memorizzare le versioni (ti interessano veramente i vecchi dati) o vuoi solo avere gli ultimi dati approvati? –

risposta

9

La dimensione è il tuo nemico. Se hai a che fare con un sacco di dati e un numero elevato di righe, avere lo storico mescolato con la corrente ti martellerà. Avrai anche problemi se ti unisci ad altri dati assicurandoti di avere le righe giuste.

Se è necessario salvare i dati cronologici per mostrare i cambiamenti nel tempo, andrei con la tabella storica separata, che aggiorna i dati reali e reali una volta approvata. È solo più pulito.

Se si dispone di molti tipi di dati che avranno questo meccanismo ma non è necessario mantenere un record cronologico, suggerirei una coda comune per esaminare gli elementi in sospeso, ad esempio memorizzati come xml. Ciò consentirebbe agli amministratori di leggere una sola tabella e consentirebbe di aggiungere questa funzionalità a qualsiasi tabella del sistema in modo abbastanza semplice.

+0

Come gestisci le colonne che cambiano i nomi? Hai molti elementi in sospeso e ora i tuoi dati in sospeso non corrispondono alla colonna in cui saranno archiviati. – Sixty4Bit

19

Definitivamente memorizzarli nella tabella principale con una colonna per indicare se i dati sono approvati o meno.

Quando la modifica è approvata, non è necessaria alcuna copia. Il lavoro extra per filtrare i dati non approvati è il tipo di cose che i database dovrebbero fare, quando ci pensi. Se indicizzi la colonna approvata, non dovrebbe essere troppo oneroso per fare la cosa giusta.

+1

Assicurati di aver inserito un indice nella colonna della bandiera di approvazione! – Martin

+0

Batteremi alla risposta :) – jdmichal

+2

Questa è una cancellazione essenzialmente morbida al contrario. – Jim

0

Penso che la seconda via sia l'approccio migliore, semplicemente perché si adatta meglio a più tabelle. Inoltre, l'elaborazione aggiuntiva sarebbe minima, in quanto è possibile creare un indice per la tabella in base al bit "approvato" ed è possibile specializzare le query in modo da selezionare le voci approvate (per la visualizzazione) o non approvate (per l'approvazione).

3

Dato il movimento di conformità SOx che è stato spinto di fronte alla maggior parte delle società quotate in borsa, ho avuto un bel po 'di esperienza in questo settore. Di solito ho usato una tabella separata con un time stamped in sospeso con una sorta di colonna di flag. La persona incaricata dell'amministrazione di questi dati ottiene un elenco di modifiche in sospeso e può scegliere di accettare o meno di accettare. Quando un pezzo di dati viene accettato, io uso i trigger per integrare i nuovi dati nella tabella. Anche se alcune persone non amano il metodo di trigger e preferiscono codificarlo nei processi memorizzati. Questo ha funzionato bene per me, anche in database piuttosto grandi. La complessità può essere un po 'difficile da gestire, specialmente nel trattare una situazione in cui un cambiamento è direttamente in conflitto con un altro cambiamento e su quale ordine elaborare questi cambiamenti. La tabella contenente i dati della richiesta non può mai essere eliminata, dal momento che detiene le "briciole di pane" per così dire che sono necessarie nel caso in cui sia necessario rintracciare ciò che è accaduto in una particolare situazione. Ma in qualsiasi approccio, i rischi devono essere valutati, come quello che ho citato con i dati in conflitto, e un livello di logica aziendale deve essere in atto per determinare il processo in queste situazioni.

Personalmente non mi piace lo stesso metodo di tabella, perché nei casi di archivi di dati che vengono costantemente modificati, questi dati aggiuntivi in ​​una tabella possono inutilmente impantanarsi la richiesta sul tavolo e richiederebbero molto di più dettagli su come stai indicizzando la tabella e i tuoi piani di esecuzione.

1

Poiché si tratta di un'app Web, suppongo che ci siano più letture che scritture e che tu voglia qualcosa di abbastanza veloce, e la tua risoluzione di conflitto (cioè approvazioni fuori servizio) comporta lo stesso comportamento - ultimo aggiornamento è quello che viene utilizzato.

Entrambe le strategie che proponi sono simili in entrambe mantengono una riga per set di modifiche, devono occuparsi di conflitti ecc., L'unica differenza è se memorizzare i dati in una o due tabelle. Dato lo scenario, due tabelle sembrano la soluzione migliore per motivi di prestazioni. Puoi anche risolvere questo problema con una tabella e una vista delle modifiche approvate più recenti se il tuo database lo supporta.

1

Un'altra idea sarebbe avere tre tabelle.

  • Uno sarebbe la tabella principale per contenere i dati originali.
  • Il secondo dovrebbe contenere i dati proposti.
  • Il terzo contiene i dati storici.

Questo approccio consente di eseguire rapidamente e facilmente il rollback e fornisce anche un audit trail se necessario.

4

Io lavoro in un dominio bancario e abbiamo questa necessità - che le modifiche apportate da un utente devono essere riflesse solo dopo essere state approvate da un altro.Il design usiamo è come sotto

  1. principale Tabella A
  2. un'altra tabella B che memorizza il record modificato (e così è esattamente simile ai primi) + 2 colonne addizionali (una FKey a C e un codice di indicare il tipo di modifica)
  3. Una terza tabella C che memorizza tutti i record che necessitano di approvazione
  4. Una quarta tabella D che memorizza la cronologia (probabilmente non è necessario).

Consiglio questo approccio. Gestisce tutti gli scenari inclusi gli aggiornamenti e le cancellazioni con molta grazia.

+0

Come gestiresti le aggiunte? – Lucifer

2

vorrei creare una tabella con una bandiera e creare una vista come

CREATE OR REPLACE VIEW AS 

    SELECT * FROM my_table where approved = 1 

Può aiutare a dipendenze separati tra l'aprovement e le query. Ma potrebbe essere non è l'idea migliore se è necessario apportare aggiornamenti alla vista.

I record in movimento potrebbero avere alcune considerazioni sulle prestazioni. Ma i tavoli partizionati potrebbero fare qualcosa di molto simile.

Problemi correlati