Domanda

Sto cercando di scoprire se dovrei utilizzare la logica aziendale critica in un trigger o in un vincolo all'interno del mio database.
Finora ho aggiunto la logica nei trigger in quanto mi dà il controllo su ciò che succederà dopo e significa che posso fornire messaggi utente personalizzati invece di un errore che probabilmente confonderà gli utenti.

C'è qualche notevole miglioramento delle prestazioni nell'uso dei vincoli sui trigger e quali sono le migliori pratiche per determinare quale utilizzare.

È stato utile?

Soluzione

Vincoli verso il basso!

  • Con i vincoli si specificano i principi relazionali, cioè i fatti sui dati. Non dovrai mai cambiare i tuoi vincoli, a meno che alcuni fatti non cambino (cioè nuovi requisiti).

  • Con i trigger si specifica come gestire i dati (in inserti, aggiornamenti, ecc.). Questo è un "non relazionale" modo di fare le cose.

Per spiegarmi meglio con un'analogia: il modo corretto di scrivere una query SQL è specificare " cosa vuoi " invece di " come ottenerlo " - lascia che RDBMS trovi il modo migliore per farlo per te. Lo stesso vale qui: se usi i trigger devi tenere a mente varie cose come l'ordine di esecuzione, il collegamento a cascata, ecc ... Lascia che SQL lo faccia per te con dei vincoli, se possibile.

Questo non vuol dire che i trigger non abbiano usi. Lo fanno: a volte non è possibile utilizzare un vincolo per specificare alcuni fatti sui dati. È estremamente raro però. Se ti capita molto , allora probabilmente c'è qualche problema con lo schema.

Altri suggerimenti

Best practice : se puoi farlo con un vincolo, usa un vincolo.

I trigger non sono così male come vengono screditati (se usati correttamente), anche se userei sempre un vincolo ove possibile. In un RDMS moderno, l'overhead delle prestazioni dei trigger è paragonabile ai vincoli (ovviamente, ciò non significa che qualcuno non possa inserire un codice orribile in un trigger!).

Occasionalmente è necessario utilizzare un trigger per applicare un vincolo 'complesso' come la situazione di voler imporre che uno e solo uno dei due campi chiave esterna di una tabella siano popolati (ho visto questa situazione in alcuni domini modelli).

Il dibattito sul fatto che la logica aziendale debba risiedere nell'applicazione anziché nel DB, dipende in una certa misura dall'ambiente; se hai molte applicazioni che accedono al DB, sia i vincoli che i trigger possono servire da protezione finale che i dati sono corretti.

I trigger possono sbocciare in un problema di prestazioni. Più o meno nello stesso momento in cui accadono, sono anche diventati un incubo per la manutenzione. Non riesci a capire cosa sta succedendo e (bonus!) L'applicazione si comporta in modo irregolare con " spurio " problemi di dati. [Davvero, sono problemi scatenanti.]

Nessun utente finale tocca direttamente SQL. Usano i programmi applicativi. I programmi applicativi contengono la logica aziendale in un modo molto più intelligente e più gestibile rispetto ai trigger. Inserire la logica dell'applicazione nei programmi dell'applicazione. Inserisci i dati nel database.

A meno che tu e i tuoi " utenti " non condividere un linguaggio comune, puoi spiegare loro le violazioni dei vincoli. L'alternativa - non spiegando - trasforma un semplice database in un problema perché confonde i dati e il codice dell'applicazione in un pantano non mantenibile.

" Come posso avere la certezza assoluta che tutti usano correttamente il modello di dati? "

Due (e mezzo) tecniche.

  1. Assicurati che il modello sia giusto : corrisponde al dominio del problema del mondo reale. Nessun hack o soluzione alternativa o scorciatoie che possono essere risolti solo attraverso complesse spiegazioni sventolanti, procedure memorizzate e trigger.

  2. Aiuta a definire il livello del modello di business delle applicazioni. Il livello del codice dell'applicazione che tutti condividono e riutilizzano.

    a. Inoltre, assicurati che il livello del modello soddisfi le esigenze delle persone. Se il livello del modello ha i metodi e le raccolte giusti, c'è meno incentivo a bypassarlo per ottenere l'accesso diretto ai dati sottostanti. In generale, se il modello è giusto, questa non è una preoccupazione profonda.

I trigger sono un disastro ferroviario in attesa di accadere. I vincoli non lo sono.

Oltre agli altri motivi per utilizzare i vincoli, l'ottimizzatore Oracle può utilizzare i vincoli a proprio vantaggio.

Ad esempio, se hai un vincolo che dice (Amount > = 0) e quindi esegui una query con DOVE (Amount = -5) Oracle sa immediatamente che lì non sono righe corrispondenti.

Vincoli e trigger sono per 2 cose diverse. I vincoli vengono utilizzati per vincolare il dominio (input validi) dei tuoi dati. Ad esempio, un SSN verrebbe archiviato come char (9), ma con un vincolo di [0-9] [0-9] [0-9] [0-9] [0-9] [0-9] [ 0-9] [0-9] [0-9] (tutto numerico).

I trigger sono un modo per applicare la logica aziendale nel database. Prendendo di nuovo SSN, forse una pista di controllo deve essere mantenuta ogni volta che un SSN viene cambiato - questo sarebbe fatto con un trigger,

In generale, i problemi di integrità dei dati in un RDBMS moderno possono essere gestiti con alcune variazioni di un vincolo. Tuttavia, a volte ti imbatterai in una situazione in cui la normalizzazione impropria (o i requisiti modificati, con conseguente normalizzazione impropria) prevengono un vincolo. In tal caso, un trigger potrebbe essere in grado di applicare il vincolo, ma è opaco per RDBMS, il che significa che non può essere utilizzato per l'ottimizzazione. È anche " nascosto " logica e può essere un problema di manutenzione. Decidere se riformattare lo schema o utilizzare un trigger è una richiesta di giudizio in quel momento.

In generale preferirei i vincoli e il mio codice rileverebbe errori del server SQL e presenterebbe qualcosa di più amichevole per l'utente.

@onedaywhen

Puoi avere una query come vincolo in SQL Server, devi solo essere in grado di inserirla in una funzione scalare: http://www.eggheadcafe.com/software/aspnet/30056435/check-contraints-and-tsql.aspx

@Mark Brackett: " I vincoli sono usati per limitare il dominio ... I trigger sono un modo per applicare la logica di business " ;: Non è così semplice in SQL Server perché la funzionalità dei suoi vincoli è limitata, ad es. SQL-92 non ancora completo. Prendi l'esempio classico di una "chiave primaria" in sequenza in una tabella di database temporale: idealmente utilizzerei un vincolo CHECK con una sottoquery per evitare periodi di sovrapposizione per la stessa entità, ma SQL Server non può farlo quindi devo usare un grilletto. Manca inoltre la capacità di SQL-92 di rinviare il controllo dei vincoli, ma invece sono (in effetti) controllati dopo ogni istruzione SQL, quindi potrebbe essere necessario un trigger per aggirare le limitazioni di SQL Server.

Se possibile usare i vincoli. Tendono ad essere leggermente più veloci. I trigger devono essere utilizzati per la logica complessa che un vincolo non può gestire. Anche la scrittura di trigger è complicata e se scopri che devi scrivere un trigger, assicurati di utilizzare istruzioni basate su set perché i trigger funzionano contro l'intero inserimento, aggiornamento o eliminazione (Sì, ci saranno momenti in cui è interessato più di un record, piano su questo!), non solo un record alla volta. Non utilizzare un cursore in un trigger se può essere evitato.

Per quanto riguarda se inserire la logica nell'applicazione anziché un trigger o un vincolo. NON FARLO!!! Sì, le applicazioni devono essere controllate prima di inviare i dati, ma l'integrità dei dati e la logica aziendale devono essere a livello di database oppure i tuoi dati verranno incasinati quando più applicazioni si agganciano, quando inserimenti globali vengono eseguiti all'esterno dell'applicazione ecc. Dati l'integrità è la chiave per i database e deve essere applicata a livello di database.

@Meff: ci sono potenziali problemi con l'approccio dell'uso di una funzione perché, in poche parole, i vincoli CHECK di SQL Server sono stati progettati con una singola riga come unità di lavoro e presentano dei difetti quando si lavora su un set di risultati. Per ulteriori dettagli al riguardo, consultare: [ http://blogs.conchango.com/davidportas/archive/2007/02/19/Trouble-with-CHECK-Constraints.aspx] [1] .

[1]: Blog di David Portas: Problemi con i vincoli CHECK.

Come per Skliwz. Solo per farti sapere che un uso canonico del trigger è la tabella di controllo. Se molte procedure aggiornano / inseriscono / eliminano una tabella che si desidera controllare (chi ha modificato cosa e quando), il trigger è il modo più semplice per farlo. un modo è semplicemente aggiungere un flag nella tabella (attivo / inattivo con qualche vincolo di unicità) e inserire qualcosa nella tabella di controllo.

Un altro modo se si desidera che la tabella non contenga i dati storici è copiare la prima riga nella tabella di controllo ...

Molte persone hanno molti modi per farlo. Ma una cosa è certa, dovrai eseguire un inserimento per ogni aggiornamento / inserimento / eliminazione in questa tabella

Per evitare di scrivere l'inserto in dozzine di luoghi diversi, puoi qui utilizzare un trigger.

Sono d'accordo con tutti qui sui vincoli. Usali il più possibile.

C'è una tendenza ad abusare dei trigger, specialmente con i nuovi sviluppatori. Ho visto situazioni in cui un trigger attiva un altro trigger che attiva un altro trigger che ripete il primo trigger, creando un trigger a cascata che lega il server. Si tratta di un utente non ottimale dei trigger; o)

Detto questo, i trigger hanno il loro posto e dovrebbero essere usati quando appropriato. Sono particolarmente utili per tenere traccia delle modifiche ai dati (come menzionato da Mark Brackett). Devi rispondere alla domanda "Dove ha più senso mettere la mia logica di business"? La maggior parte delle volte penso che appartenga al codice, ma devi tenere una mente aperta.

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