tags:

views:

2396

answers:

20

Are database triggers a bad idea?

In my experience they are evil, because they can result in surprising side effects, and are difficult to debug (especially when one trigger fires another). Often developers do not even think of looking if there is a trigger.

On the other hand, it seems like if you have logic that must occur evertime a new FOO is created in the database then the most foolproof place to put it is an insert trigger on the FOO table.

The only time we're using triggers is for really simple things like setting the ModifiedDate.

+1  A: 

If there are side effects, it's a problem by design. In some database systems, there is no other possibility to set an autoincrement field i.e. for a primary key ID field.

Peter
+12  A: 

No, they're actually a good idea. If there's a problem with your specific triggers, then you're not doing them right, but that usually means there's a problem with your implementation, not the concept of triggers themselves :-).

We use triggers a great deal because it places the DBMS-specific activity under the control of the DBAs where it belongs. Users of a DBMS should not have to worry about that sort of stuff.

For example, without triggers, such wondrous things as auto-generated columns wouldn't exist and you'd have to process a function on each row when selecting them. That's likely to kill DBMS performance, far better to create the auto-generated column at insert/update time since that's the only time it changes.

Also, lack of triggers would prevent data rules from being enforced at the DBMS such as pre-triggers to ensure columns have a specific format. Note that this is different from data integrity rules which are generally just foreign key look ups.

paxdiablo
"process a function on each row when selecting them". It is better to use a function based index for this purpose than a trigger.
tuinstoel
Not necessarily, the trigger will probably only run when the row is inserted or updated. The function-based index will run for every select. Depending on usage pattern one is probably better than the other. But neither is ALWAYS better than the other.
jmucchiello
@tuinstoel: I have to agree with your statement *some* of the time. Oracle, for example, will only create function-based indexes if it can prove that the function is deterministic. Sometimes that just cannot be proved (for example, if the function involves a look-up from a table, even if you *know* that the table's data never changes).
Adam Paynter
+6  A: 

Triggers seem to work well for audit logging.

derobert
+28  A: 

The main problems with triggers are a) they are completely Global - they apply no matter what the context of the table activity; and b) they are stealthy; it's easy to forget they are there until they hurt you with unintended (and very mysterious) consequences.

Which just means they need to be carefully used for the proper circumstances; which in my experience is limited to relational integrity issues (sometimes with finer granularity than you can get declaratively); and never for business or transactional purposes. YMMV.

le dorfier
Those are 2 advantages, in some cases.
John Nolan
"Stealthy" is a great word, yeah -- well said. That's exactly why I tend to shy away from them: too often they're forgotten or ignored. In my personal experience, revisiting triggers is often accompanied by a smack to my own forehead.
Christian Nunciato
You can build the context into the trigger. A simple if statement can achieve quite a lot.
tuinstoel
@Nolan, I can agree about Global being a benefit - that's when they are appropriate. But stealthy - I'm having a harder time seeing the advantage in that. @tuinstoel, I'm not sure how a trigger can have its context built in, since it takes no arguments.
le dorfier
I'm curious about your "never for business or transactional purposes" quote, @le dorfier. Why do you think that's not appropriate?
paxdiablo
Several independent reasons, each of which could be debated but together I think they are pursuasive. 1. Business rules belong in the BL together, where they are accessible at the proper granularity for UI validation and exception handling.
le dorfier
2. Triggers are global and comparatively immutable. Business rules are local and subject to local changes which shouldn't be coupled to global stealth triggers. 3. Personal experience. @Nunciato phrases it nicely above.
le dorfier
I'd be extremely careful with using triggers to create anything related to relational integrity. About 90-99% of those triggers I have seen where a major data integrity problem waiting to happen. In the other 1-10% it actually happened.
Jens Schauder
Global is why they are good and necessary for data integrity and things like auditing. It isn't a minus, it's a plus.
HLGEM
A: 

Indeed, quite often triggers are being misused. Actually in most cases you don't even need them. But that doesn't make them necessarily bad.

A scenario that comes to my mind where triggers are useful is when you have a legacy application for which you don't have the source code and there is no way to change it.

ionut bizau
+5  A: 

I agree. The problems with triggers is people, not triggers. Although it's more to look at, more to consider and increases the onus on coders checking things correctly, we don't discard indexes to make our lives simpler. (Bad indexes can be just as bad as bad triggers)

The importance of triggers (in my mind) is that...
- Any system should always be in a valid state
- Code to enforce this valid state should be centralised (not written in every SP)

From a maintenance point of view, a trigger is very useful to competant coders and problems for more junior/amateur ones. Yet, these people need to learn and grow somehow.

I guess it comes down to your working environment. Do you have reliable people who learn well and can be trusted to be methodical? If not you seemingly have two choices:
- Accept that you'll have to lose functionality to compensate
- Accept that you need different people or better training and management

They sound harsh, and I guess that they are. But it's the basic truth, in my mind...

Dems
+4  A: 

Mostly, yes.

The difficulty with a trigger is that it does stuff "behind your back"; the developer maintaining the application could easily not realise it's there and make changes which screw things up without even noticing.

It creates a layer of complexity which just adds maintenance work.

Rather than using a trigger, a stored procedure / routine, can generally be made to do the same thing, but in a clear and maintainable manner - calling a stored routine means the developer can look at its source code and see exactly what's happening.

MarkR
This is the advantage of a trigger not the disadvatage! Stored procs cannot be guaranteed to be invoked for every change to the data. THere are many ways data can be changed besides the GUI.
HLGEM
+2  A: 

I know developers who think triggers should always be used where it is the most direct way of achieving the functionality they want, and developers who never will. It's almost like dogma between the two camps.

However I personally completely agree with MarkR - you can (nearly) always write code functionally equivalent to the trigger that will be more perspicuous and therefore easier to maintain.

DanSingerman
I had to vote for an answer using my favorite word!
Stephen Denne
A: 

Not evil. They actually simplify things like

1.Logging/auditing of changes to records or even database schemas

You could have a trigger on ALTER TABLE that rolls back changes in your production environment. This should prevent any accidental table modifications.


2.Enforcing referential intrgrity (primary/foreign key relationships, etc) across multiple databases

Chris
You can roll back DDL statements?
Andrew Swan
Generally not. The only way to stop that is to remove that permission from users' logins.
jmucchiello
In some database engines you can (eg. PostgreSQL).
Nicolás
+1  A: 

Triggers are extremely powerful and useful, there are any number of scenarios where a trigger is the best solution to a problem.

They are also a very good "hack" tool. There are often situations where you are not in immediate control of both the code and the database. If you have to wait 2 months for the next major release of your code, yet you can apply a patch to your database immediately then you can put a trigger on a table to perform some additional functionality. Then when the code release is possible you can replace this trigger with your coded version of the same functionality if desired.

At the end of the day, everything is "evil" if you don't know what it's doing. Deciding that triggers are because there are developers that don't understand them is the same as arguing that cars are evil because some people can't drive...

Robin Day
+1  A: 

I think they can be evil, but only as evil as anything else in development.

Although I don't really have much experience with them I did have them on a recent project I worked on which has lead me to this conclusion. The problem I have with them is they can cause business logic to end up in two locations, a code library and a database.

I see it as a similar argument with using sprocs. You'll often have developers who are really good at SQL writing business logic into the database, while people who are not will have their business logic elsewhere.

So my rule-of-thumb is look at what the structure of your project is. If it seems viable to have business logic stored in the database then it could be useful to have triggers.

Slace
+2  A: 

Nah, they're not evil - they're just misunderstood :-D

Triggers have a valid use, but far too often as a retro-hack that ultimately makes things worse.

If you're developing a DB as part of an application the logic should always be in the code or sprocs making the call. Triggers will just lead to debug-pain later on.

If you understand how locking, deadlocking and how DBs access files on disk then using triggers in the right way (for instance auditing or archiving direct DB access) can be really valuable.

Keith
A: 

To say that they are evil is an exageration but they can cause of mesh. When the firing of one trigger causes other triggers to fire it becomes really complicated. Let's say they are troublesome: http://www.oracle.com/technology/oramag/oracle/08-sep/o58asktom.html

Doing business logic in Oracle with triggers is harder than it seems because of multi concurrency issues. You don't see changes in another session until the other sessions commits.

tuinstoel
+1  A: 

Triggers have their uses - logging/auditing and maintaining a "last modified" date are two very good uses which have been mentioned in previous replies.

However, one of the core tenets of good design is that business rules/business logic/whatever you want to call it should be concentrated in a single place. Putting some of the logic in the database (via triggers or stored procs) and some in the application violates that principle. Duplicating the logic in both places is even worse, as they will invariably get out of sync with each other.

There is also the "principle of least surprise" issue which has already been mentioned.

Dave Sherohman
That's correct it should be in one place, the database. Logic that affects the integrity of the data must ALWAYS be in the database and never in an application where it might or might not get called when affecting data in the database.
HLGEM
@HLGEM: That depends on whether the database can possibly have access to information that allows it to tell whether the data is valid. It's not always the case that it can; when the validator is in another organization (e.g., for credit card or bank account details) then the DB can't know whether it is right — assuming this isn't the bank's DB! — and it will have to rely on the application for enforcement. What you don't want is to have the database making random connections to third-party services, as that is bad when it comes to server deployment.
Donal Fellows
@HLGEM: While I'm not ready to completely rule out the option of putting all application logic into the database, I find that it tends to work better to put it elsewhere, generally a reusable OO layer that can be used for all apps accessing the database. So long as your app only accesses the database through the object layer, the same guarantees of the logic always being called will still apply.
Dave Sherohman
Never worked on a business application that only inserted data into the database through the Object layer and I wouildn't want to work on one. It's stupid to put million record imports or updates of all prices through a process designed to handle only one record ata time. THe Object layer is exactly the wrong place to enforce data integrity which is why so many datbases have integrity problems.
HLGEM
+2  A: 

With the name Triggers they must be dangerous, but.. We have the 2nd Amendment to protect the right to use them.

kenny
Oh no, someone triggered kenny.
Hogan
+3  A: 

Tools are never evil. Applications of those tools can be evil.

Andy Webb
+3  A: 

Triggers are a good tool when used properly. Expecially for things like auditing changes, populating summarization tables, etc.

Now they can be "evil" if you end up in "trigger hell" with one trigger that kicks off other triggers. I once worked on a COTS product where they had what they called "flex triggers." These triggers were stored in a table as dynamic sql stings are were compiled every time they were executed. Compiled triggers would do a look up and see if that table had any flex triggers to run and then compile and run the "flex" trigger. In theory this sounded like a really cool idea because the product was easily customized but the reality was the database pretty much exploded due to all the compiles it had to do...

So yeah, they're great if you keep what you're doing in perspective. If it is something pretty simple like auditing, summarizing, auto-sequencing, etc, no prob. Just keep in mind the growth rate of the table and how the trigger will impact performance.

tmeisenh
+1  A: 

I think triggers are not only not evil, but necesasary to good database design. Application programmers think that databases are only affected by their application. They are often wrong. If data integrity is to be maintained no matter whare the data change came from triggers are a requirement and it is foolish to avoid them because some programmers are too ethnocentric to consider that something other than their prized application may be affecting things. It isn't hard to design or test or troubleshoot a trigger if you are a competent database developer. Nor it is difficult to determine that a trigger is causing an unexpected result if it occurs to you (as it does to me) to look there. If I get an error saying a table that I'm not referencing in my sp has an FK error, I know without even thinking about it that trigger is causing the problem and so should any competent database developer. Putting business rules only in the application is the number one cause I have found of bad data as others have no idea that rule even exists and violate it in their processes. Data-centric rules belong in the database and triggers are key to enforcing the more complex ones.

HLGEM
A: 

Idea of triggers is not evil, limiting nesting of triggers is evil.

alpav
+1  A: 

They are definitely not evil. I found triggers precious during refactoring of database schemas, while renaming a column, or splitting a column into two columns or vice-versa (example: name/surname case) and assisting the transition.

They are also very useful for auditing.

Stefano Borini