Qual è il modo migliore per archiviare le modifiche ai record del database che richiedono l'approvazione prima di essere visibili?

StackOverflow https://stackoverflow.com/questions/103766

  •  01-07-2019
  •  | 
  •  

Domanda

Devo archiviare 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 quelle modifiche sono ancora in sospeso, visualizzerei comunque la vecchia versione dei dati. Quale sarebbe il modo migliore per archiviare queste modifiche in attesa di approvazione?

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

Qualche esperienza personale con questi metodi o altri che potrebbero essere buoni?

Aggiornamento: solo per chiarire, in questa particolare situazione non mi interessano molto i dati storici. Ho solo bisogno di un modo per approvare le modifiche apportate da un utente prima che diventino attive sul sito. Pertanto, un utente modificherà il proprio profilo " " e quindi un amministratore esaminerà quella modifica e la approverà. Una volta approvato, diventerà il valore visualizzato e non sarà necessario conservare la versione precedente.

Qualcuno ha provato la soluzione di seguito in cui memorizzi le modifiche in sospeso da qualsiasi tabella che deve tracciarle come XML in una tabella PendingChanges speciale? Ogni record avrebbe una colonna che indicava la tabella per cui erano state apportate le modifiche, una colonna che forse memorizzava l'id del record che sarebbe stato modificato (null se si tratta di un nuovo record), una colonna datetime da archiviare al momento della modifica e una colonna per memorizzare l'xml del record modificato (potrebbe serializzare il mio oggetto dati). Poiché non ho bisogno della cronologia, dopo l'approvazione di una modifica, la tabella reale verrà aggiornata e il record PendingChange potrebbe essere eliminato.

Qualche idea su quel metodo?

È stato utile?

Soluzione

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

Se hai bisogno di salvare i dati storici per mostrare i cambiamenti nel tempo, andrei con la tabella cronologica separata che aggiorna i dati reali dal vivo una volta approvati. È solo un detergente universale.

Se hai molti tipi di dati che avranno questo meccanismo ma non hai bisogno di tenere un registro storico, suggerirei un talbe di coda comune per rivedere gli elementi in sospeso, diciamo archiviati come xml. Ciò consentirebbe agli amministratori di leggere solo una tabella e di aggiungere abbastanza facilmente questa funzionalità a qualsiasi tabella del sistema.

Altri suggerimenti

Conservali sicuramente 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 fare la cosa giusta.

Lavoro in un settore bancario e abbiamo questa necessità: le modifiche apportate da un utente devono essere riflesse solo dopo essere state approvate da un altro. Il design che utilizziamo è il seguente

  1. Tabella principale A
  2. Un'altra tabella B che memorizza il record modificato (e quindi è esattamente simile alla prima) + 2 colonne aggiuntive (un FKey in C e un codice per indicare il tipo di modifica)
  3. Una terza tabella C che memorizza tutti questi record che richiedono l'approvazione
  4. Una quarta tabella D che memorizza la cronologia (probabilmente non ti serve).

Raccomando questo approccio. Gestisce tutti gli scenari, inclusi gli aggiornamenti e le eliminazioni con molta grazia.

Dato il movimento di conformità SOx che è stato spinto di fronte alla maggior parte delle società quotate in borsa, ho avuto un po 'di esperienza in questo settore. Di solito ho usato una tabella separata con un timestamp in attesa di modifiche con una sorta di colonna flag. Il responsabile della gestione di questi dati ottiene un elenco di modifiche in sospeso e può scegliere di accettare o meno. Quando un pezzo di dati viene accettato, utilizzo i trigger per integrare i nuovi dati nella tabella. Anche se ad alcune persone non piace il metodo trigger e preferiscono codificarlo nei proc memorizzati. Questo ha funzionato bene per me, anche in database piuttosto grandi. La complessità può diventare un po 'difficile da affrontare, soprattutto quando si tratta di una situazione in cui una modifica è direttamente in conflitto con un'altra modifica e in quale ordine elaborare queste modifiche. La tabella contenente i dati della richiesta non potrà mai essere eliminata, poiché contiene il "pangrattato" per così dire che sono necessari nel caso in cui sia necessario risalire a ciò che è accaduto in una situazione particolare. 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 extra in una tabella possono imprevedere inutilmente la richiesta sulla tabella e richiederebbero molti più dettagli a come stai indicizzando la tabella e i tuoi piani di esecuzione.

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 separare le dipendenze tra l'approvazione e le query. Ma potrebbe non essere la migliore idea se è necessario effettuare aggiornamenti alla vista.

Lo spostamento dei record potrebbe avere alcune considerazioni sulle prestazioni. Ma le tabelle partizionate potrebbero fare qualcosa di abbastanza simile.

Dato che si tratta di un'app Web, suppongo che ci siano più letture che scritture e tu desideri qualcosa di ragionevolmente veloce e la risoluzione dei conflitti (ovvero le approvazioni non ordinate) porta allo stesso comportamento - l'ultimo aggiornamento è quello che viene utilizzato.

Entrambe le strategie che proponi sono simili in quanto contengono entrambe una riga per serie di modifiche, devono affrontare conflitti ecc., l'unica differenza è se archiviare i dati in una o due tabelle. Dato lo scenario, due tabelle sembrano la soluzione migliore per motivi di prestazioni. Puoi anche risolverlo con una tabella e una vista delle modifiche approvate più recenti se il tuo database lo supporta.

Ancora un'altra idea sarebbe quella di avere tre tavoli.

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

Questo approccio ti dà la possibilità di tornare indietro rapidamente e facilmente e ti dà anche una pista di controllo se ne hai bisogno.

Penso che il secondo modo 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 basato sul bit 'approvato' e si possono specializzare le query per estrarre voci approvate (per la visualizzazione) o non approvate (per l'approvazione).

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