Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Multiple triggers vs a single trigger

Scenario:

Each time data is inserted/updated/deleted into/in/from a table, up to 3 things need to happen:

  1. The data needs to be logged to a separate table
  2. Referencial integrity must be enforced on implicit related data (I'm referring to data that should be linked with a foreign key relationship, but isn't: eg. When a updating Table1.Name should also update Table2.Name to the same value)
  3. Arbitrary business logic needs to execute

The architecture and schema of the database must not be changed and the requirements must be accomplished by using triggers.

Question

Which option is better?:

  1. A single trigger per operation (insert/update/delete) that handles multiple concerns (logs, enforces implicit referencial integrity, and executes arbitrary business logic). This trigger could be named D_TableName ("D" for delete).
  2. Multiple triggers per operation that were segregated by concern. They could be named:

    • D_TableName_Logging - for logging when something is deleted from
    • D_TableName_RI
    • D_TableName_BL

I prefer option 2 because a single unit of code has a single concern. I am not a DBA, and know enough about SQL Server to make me dangerous.

Are there any compelling reasons to handle all of the concerns in a single trigger?

like image 366
Dan Avatar asked Jan 03 '13 19:01

Dan


People also ask

Can you have more than one trigger?

You can create multiple triggers for the same subject table, event, and activation time. The order in which those triggers are activated is the order in which the triggers were created. Db2 records the timestamp when each CREATE TRIGGER statement executes.

What are the three types of triggers?

Here, I'll discuss three types of trigger: external, internal, and synthetic. These each have different strengths and weaknesses, and each can be used to design great behaviors that form lasting habits.

Can we write multiple triggers on single object?

Multiple Triggers on the same objectWriting multiple triggers renders the system unable to recognize the order of execution. Moreover, each trigger that is invoked does not get its own governor limits. Instead, all code that is processed, including the additional triggers, share those available resources.


3 Answers

Wow, you are in a no-win situation. Who ever requested that all this stuff be done via triggers should be shot and then fired. Enforcing RI via triggers?

You said the architecture and schema of the database must not be changed. However, by creating triggers, you are, at the very least, changing the schema of the database, and, it could be argued, the architecture.

I would probably go with option #1 and create additional stored procs and UDFs that take care of logging, BL and RI so that code is not duplicated amoung the individual triggers (the triggers would call these stored procs and/or UDFs). I really don't like naming the triggers they way you proposed in option 2.

BTW, please tell someone at your organization that this is insane. RI should not be enforced via triggers and business logic DOES NOT belong in the database.

like image 162
Randy Minder Avatar answered Sep 18 '22 12:09

Randy Minder


Doing it all in one trigger might be more efficient in that you can possibly end up with fewer operations against the (un indexed) inserted and deleted tables.

Also when you have multiple triggers it is possible to set the first and last one that fires but any others will fire in arbitrary order so you can't control the sequence of events deterministically if you have more than 3 triggers for a particular action.

If neither of those considerations apply then it's just a matter of preference.

Of course it goes without saying that the specification to do this with triggers sucks.

like image 45
Martin Smith Avatar answered Sep 18 '22 12:09

Martin Smith


I agree with @RandyMinder. However, I would go one step further. Triggers are not the right way to approach this situation. The logic that you describe is too complicated for the trigger mechanism.

You should wrap inserts/updates/deletes in stored procedures. These stored procedures can manage the business logic and logging and so on. Also, they make it obvious what is happening. A chain of stored procedures calling stored procedures is explicit. A chain of triggers calling triggers is determined by insert/update/delete statements that do not make the call to the trigger explicit.

The problem with triggers is that they introduce dependencies and locking among disparate tables, and it can be a nightmare to disentangle the dependencies. Similarly, it can be a nightmare to determine performance bottlenecks when the problem may be located in a trigger calling a trigger calling a stored procedure calling a trigger.

like image 42
Gordon Linoff Avatar answered Sep 18 '22 12:09

Gordon Linoff