29/03/2024 - Sgrubak ha scritto:
Vero ma le operazioni massive o manutentive le vedo più come un qualcosa di sporadico/eccezionale. Nel caso, avrò sicuramente molte precauzioni da prendere e disabilitare eventuali trigger credo venga naturale.
Una operazione massiva può essere banalmente quella di dover inserire e/o aggiornare un numero di record in modalità batch o per “row set” invece che “row by row”. Non mi riferisco esclusivamente a un intervento di manutenzione sporadico.
I trigger risultano estremamente limitativi da questo punto di vista e sono spesso un “collo di bottiglia”, analogamente all'uso di cursori, poiché costituiscono codice SQL che viene eseguito “a fronte di qualcosa” e non per richiesta esplicita del comando SQL che si invia al database (non fa parte dell'istruzione); in breve è un “side effect” che in alcuni contesti può generare situazioni difficili da tenere sotto controllo, come il prolungarsi della durata di una transazione, il rischio di deadlock quando ve ne sono più di uno che eseguono in ordine differente a seconda del contesto, e tante altre situazioni che qualunque DBA esperto può descriverti nella propria esperienza.
29/03/2024 - Sgrubak ha scritto:
A mio sentimento, se devo fare una INSERT mi devo limitare a quello e basta. Deve essere poi compito del DB sapere cosa succede dopo. Non dovrebbe essere lui stesso a sapere come mantenera la sua integrità?
Se devi fare una INSERT, fai una INSERT. Se le regole di business dettano che le INSERT devono essere due, il tuo codice ne deve fare due: suddividerle una nel codice C#/VB.NET e l'altra in SQL Server non ha alcuna utilità ai fini pratici, mentre rende il tutto prono a molti rischi, fermo restando che anche un eventuale “passaggio di consegne” o documentazione del progetto deve tenere conto dell'esistenza di queste due entità disgiunte ma strettamente correlate fra di loro per ricostruire il quadro completo delle operazioni che avvengono all'interno del DB.
In linea generale, un trigger è utile per scopi di audit, logging semplificato, integrazione con database esistenti per travasare dati (pochi) all'interno di altre strutture applicative che devono relazionarsi con software legacy, ma con tutte le metodologie che abbiamo a disposizione oggi (tra SOLID, TDD, ecc.), le architetture (microservizi, ecc.), i linguaggi, i framework e così via, anche se non si deve realizzare un sistema così complesso, partire creandosi scientemente un possibile problema in futuro è inaccettabile. Dal mio punto di vista, ovviamente. :)
29/03/2024 - Sgrubak ha scritto:
Credo si vada ad aumentare inutilmente la dimensione del DB salvando dati che possono comunque essere calcolati da una query.
No, l'utilità del fare un calcolo non la si misura dal fatto che un certo dato può essere sempre determinato da una query, ma da quanto velocemente si vuole arrivare a reperire quel dato: se molti utenti desiderano avere in tempi brevi (leggi istantaneamente) una certa informazione, o se l'inclusione di altre tabelle in join rende complessa (leggi lenta) la query da eseguire, in molti di questi casi il costo di ridondare il dato è di gran lunga infinitamente inferiore a quello di eseguire la query inutilmente più estesa del dovuto.
Lavorare con i database è sempre un “trade off”, ma non c'è nulla che sia del tutto inutile o utile in senso assoluto.
Lo stesso vale per i trigger, intendiamoci, e infatti il mio suggerimento di NON utilizzarli tiene conto dello scenario: non capisco come sia più rapido aggiornare una tabella correlata a un dato modificato via SQL con un trigger rispetto all'aggiungere l'esecuzione di una ulteriore UPDATE all'interno del codice, ma a parte questo giudizio di merito - come dicevo sopra - non vedo di buon occhio lo “split” di due operazioni da fare in termini di business suddividendole a priori tra codice e trigger SQL, in due posti diversi, con due linguaggi diversi, che assolvono alla persistenza nello storage (il database di SQL Server) una unica informazione.
29/03/2024 - Sgrubak ha scritto:
Potrebbe comunque starci nel caso in cui queste elaborazioni siano particolarmente “pesanti” computazionalmente e siano richieste di frequente. In quel caso potrebbe avere senso aggiornarli di volta in volta durante gli inserimenti.
Come dicevo, se l'aggiornamento è richiesto ai fini statistici, allora si elimina l'UPDATE in loco, si elimina il trigger e si delega tutto a una procedura che estrae i dati e, dalla fotografia, aggiorna di conseguenza la tabella statistica.
La mia era comunque una ipotesi: sarà l'autore della discussione (se vuole) a dirci qualcosa di più. :)