Usando i trigger o le transazioni MySQL?


8

Voglio chiedere la tua opinione sull'utilizzo di trigger o transazioni MySQL in un sito Web.

In realtà ho una paymenttabella di cronologia con - UserId | OperationId | Comment | Credits | Sign (debit or credit). Quindi ogni operazione di pagamento viene inserita in questa tabella.

Tuttavia, richiederà molto tempo calcolare ogni volta l'importo totale del credito dell'utente ogni volta che compie un'azione. Quindi ho pensato che forse è una buona idea mantenere l'importo del credito totale per ciascun utente in una profiletabella utenti .

Ecco il problema Come posso essere sicuro che l'importo totale del credito dalla profiletabella rimarrà sincronizzato con le operazioni dalla paymenttabella della cronologia?

Ho pensato di usare 2 metodi:

  • Trigger MySQL o
  • transazioni codificate nel codice sorgente

Quale è più affidabile? Cosa succede se ho un database di grandi dimensioni (oltre 100.000 utenti)?

Hai qualche suggerimento per farlo?

Il motore BD MySQL è InnoDB.

Risposte:


8

Senza dubbio, escluderei i trigger e rimarrei rigorosamente con le transazioni.

I trigger sono, per natura, procedure memorizzate. Le loro azioni sono praticamente difficili da ripristinare . Anche se tutte le tabelle sottostanti sono InnoDB, si verificherà un volume proporzionale di blocchi di riga condivisi e fastidiose intermittenze da blocchi di riga esclusivi. Questo sarebbe il caso se i trigger manipolassero le tabelle con INSERT e UPDATE stagnati per eseguire MVCC heavy duty all'interno di ogni chiamata a un trigger .

Combina questo con il fatto che protocolli di convalida dei dati adeguati non sono implementati nel linguaggio di stored procedure di MySQL . Business Intelligence può essere contenuto in un database a condizione che il linguaggio di procedura memorizzata sia in grado di gestire un ambiente transazionale . In quanto DBA MySQL, devo dire onestamente che non è il caso di MySQL. Oracle (PL / SQL), PostgreSQL (PL / pgSQL) e SQL Server (T-SQL) hanno questo vantaggio rispetto a MySQL.

Per quanto riguarda le transazioni, MySQL ha InnoDB come principale motore di archiviazione conforme ACID (motore di archiviazione Deafult in MySQL 5.5). Ha un eccellente crash recovery e obbedisce ai protocolli di conformità ACID.

Sceglierei transacitoni rispetto ai trigger ogni volta.


3

Sono d'accordo con la valutazione di Rolando. La logica aziendale deve risiedere nell'applicazione e deve apportare modifiche al database in modo transazionale.

Il ridimensionamento a 100.000 utenti, ovviamente, dipende dalla tua applicazione e dal traffico del database che genera. Con MySQL sotto un pesante carico di scrittura transazionale, potresti presto affrontare gli oneri di condivisione e / o replica del tuo set di dati al fine di mantenere una risposta accettabile per l'applicazione.

Tuttavia, ci sono alternative alla condivisione di MySQL. Uno di questi è Clustrix (il mio datore di lavoro) che è un sistema di database SQL a istanza singola ad alte prestazioni scalabile in parallelo. È un sistema di database cluster che si presenta come un singolo server MySQL. Il ridimensionamento del database descritto in questo thread senza soluzione di continuità a 100.000 utenti su una singola istanza di Clustrix non richiederebbe alcun sharding e nessuna logica applicativa aggiuntiva.


+1 per una buona risposta e spina spudorata per Clustrix. LOL !!!
RolandoMySQLDBA il

1

Buona risposta di Rolando.

Inoltre - I trigger non dovrebbero essere usati per la logica, perché un paio di trigger tra loro correlati in seguito, le cose diventeranno rapidamente confuse. Un bel set di istruzioni in una procedura memorizzata o in una procedura lato client può comprendere più chiaramente la logica aziendale rispetto a una serie di logiche nascoste nel database. Esistono anche limitazioni sui trigger rispetto alla tabella da cui vengono attivati, quindi potresti trovarti a dividere la logica in due luoghi diversi.

Inoltre, potresti trovare modi per ottimizzare in quale punto questi calcoli avvengono nel tuo server di logica aziendale, mentre un trigger si attiverà ogni volta. Ti ritroverai a disattivare il trigger, aggiornare la tabella e quindi riattivare il trigger, il che significa anche che devi inserire la logica del trigger in quel codice.

Inoltre, non è necessario disporre di tutta la logica nella parte della logica aziendale del codice, è possibile che si desideri applicare l'integrità della tabella utilizzando le procedure memorizzate. Questo può avviare una transazione, eseguire più aggiornamenti e fare in modo che le cose tornino indietro in caso di errore. In questo modo qualcuno che guarda il database può vedere la logica per l'inserimento di un ordine, per esempio. Ciò è meno importante nel mondo di oggi poiché i servizi Web possono essere l'interfaccia di accesso singolo al database; ma nel caso in cui più eseguibili abbiano accesso al DB questo può essere enorme.

Inoltre - avrai comunque delle transazioni - non eseguirai i tuoi trigger senza uno ... giusto? Quindi è bene sapere come avviare una transazione; fare delle cose; e quindi terminare una transazione. Se vedi questo modello nel tuo codice, un altro pezzo di codice che lo utilizza sarà leggero sul carico cognitivo. Un trigger, se ricordi che è lì, ti costringerà a pensare diversamente per quelle transazioni che sono interessate dal trigger, specialmente se vengono estratte altre tabelle che potrebbero anche avere trigger.

Fondamentalmente, tra un lavoro cron regolarmente pianificato (o un lavoro dell'agente di database) e buone procedure memorizzate, è possibile ottenere il 99% di ciò che si desidera. L'1%; ripensare il progetto.


In conclusione, il tuo consiglio sarebbe inequivocabilmente di NON UTILIZZARE MAI UN GRILLETTO in un'applicazione seria con logica aziendale?
Ifedi Okonkwo,

In generale si. Riesco a vedere situazioni in cui hai i trigger per eseguire strane convalide, forse multirow. Vedo anche che vengono utilizzati per generare flag di "fatti", forse questa è solo una forma di vaidation in cui il risultato della validazione è memorizzato da qualche parte. Vedo che vengono utilizzati per gli aggiornamenti delle informazioni sulla tabella (una bandiera o una tabella che indica quali righe sono state modificate, ad esempio). Tuttavia, non importa quanto siano semplici e pulite queste implementazioni, preferirei che queste cose fossero fatte in una procedura memorizzata o in un db api (cioè il modello).
Gerard ONeill,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.