Database
 sql >> Database >  >> RDS >> Database

Non ti piacciono i trigger di database? Semplicemente non sai come lavorare con loro!

Quando progettiamo database relazionali di grandi dimensioni, spesso prendiamo la decisione di discostarsi da una forma normale, ovvero la denormalizzazione.

Le ragioni possono essere diverse, come il tentativo di accelerare l'accesso ai dati specificati, i vincoli della piattaforma/il framework/gli strumenti di sviluppo utilizzati e la mancanza di competenze di uno sviluppatore/progettista di database.

A rigor di termini, un riferimento ai vincoli del quadro, ecc. è in realtà un tentativo di giustificare la mancanza di competenze.

I dati denormalizzati sono una vulnerabilità, attraverso la quale è facile portare il nostro database a uno stato non coerente (non integrale).

Cosa possiamo fare con questo?

Esempio

In un database c'è una tabella con alcune operazioni finanziarie:la ricezione e lo smaltimento di fondi su conti diversi.

Abbiamo sempre bisogno di conoscere il saldo del conto.

Nei dati normalizzati, il saldo del fondo è sempre un valore calcolato. Calcoleremo il totale degli incassi senza addebitare.

Tuttavia, è troppo costoso calcolare il saldo ogni volta che ci sono molte operazioni. Pertanto, si è deciso di memorizzare il saldo effettivo in una tabella separata. Come aggiorniamo i dati in questa tabella?

La soluzione è "come al solito"

Quasi in tutti i sistemi informativi con cui ho dovuto lavorare, questo compito veniva svolto da un'applicazione esterna, che implementava la logica di business. Sei fortunato se l'applicazione è semplice e c'è un solo punto di modifica dei dati, dal modulo nell'interfaccia utente. Tuttavia, cosa succede se ci sono alcune importazioni, API, applicazioni di terze parti, ecc. eseguite da persone e team diversi? Cosa succede se ci sono più tabelle con totali invece di uno? Cosa succede se è presente più di una tabella con operazioni?

È sempre più difficile monitorare se uno sviluppatore ha aggiornato un gruppo di tabelle durante l'aggiornamento delle operazioni. I dati perdono integrità. Il saldo del conto non corrisponde alle operazioni. Naturalmente, i test devono rivelare tali situazioni. Tuttavia, il nostro mondo non è l'ideale.

Trigger

In alternativa, i trigger vengono utilizzati per controllare l'integrità dei dati denormalizzati.

Ho sentito che i trigger rallentano notevolmente un database, quindi usarli non ha senso.

Il secondo argomento era che tutta la logica risiede in un'applicazione separata e mantenere la logica aziendale in luoghi diversi è irragionevole.

Scopriamolo.

Ritardi

All'interno della transazione viene attivato un trigger che modifica i dati nella tabella. La transazione non può essere completata finché il trigger non ha eseguito i passaggi richiesti. Pertanto, la conclusione è che i trigger devono essere "leggeri".

L'esempio della query "pesante" nel trigger è il seguente:

update totals 
set total = select sum(operations.amount) from operations where operations.account = current_account
where totals.account = current_account

Una query fa riferimento alla tabella con operazioni e riassume l'importo totale di operazioni per l'account .

Quando il database aumenta, una tale query consumerà sempre più tempo e risorse. Tuttavia, possiamo ricevere lo stesso risultato utilizzando la query light del seguente tipo:

update totals 
set total = totals.total + current_amount
where totals.account = current_account

Quando si aggiunge una nuova riga, questo trigger aumenterà semplicemente il totale dell'account senza calcolarlo. Il totale non dipende dalla quantità di dati nelle tabelle. Non ha alcun senso calcolare nuovamente il totale, poiché possiamo essere sicuri che il trigger si attiva ogni volta che si aggiunge una nuova operazione.

La rimozione o la modifica delle righe viene elaborata allo stesso modo. I trigger di questo tipo non rallenteranno le operazioni, tuttavia garantiranno l'accoppiamento e l'integrità dei dati.

Ogni volta che ho riscontrato "ritardi" durante l'aggiunta di dati a una tabella con un trigger, è stato un esempio di query così "pesante". Nella maggior parte dei casi era possibile riscriverlo in una query “facile”.

Logica aziendale

Dobbiamo distinguere le funzioni che forniscono l'integrità dei dati dalla logica aziendale. In ogni caso, faccio una domanda se i dati fossero normalizzati, avremmo bisogno di una tale funzione? Se positivo, la funzione è la logica aziendale. Se negativo, la funzione è quella di fornire l'integrità dei dati. Puoi racchiudere queste funzioni in trigger.

Tuttavia, si ritiene che sia facile implementare tutta la logica aziendale tramite DBMS, come PostgreSQL o Oracle.

Spero che questo articolo ti aiuti a ridurre il numero di bug nel tuo sistema informativo.

Naturalmente, sono lontano dal pensare che tutto ciò che è scritto qui sia la verità ultima. Nella vita reale, ovviamente, tutto è molto più complicato. Pertanto, è necessario prendere una decisione in ogni caso specifico. Usa il tuo pensiero ingegneristico!

PS

  • Nell'articolo, ho richiamato l'attenzione sull'unico aspetto dell'utilizzo dei trigger come strumento potente.
  • L'approccio descritto nell'articolo consente di evitare gli indici nelle Operazioni tabella, che, a sua volta, può accelerare il processo di aggiunta di dati a questa tabella. Ad alti volumi, questo approccio compensa facilmente il tempo dedicato al trigger.
  • È importante capire per quali strumenti dobbiamo usare. In questo caso, eviterai molti problemi.