views:

310

answers:

6

I'm working on an iPhone application with a few data relationships (Author -> Books for example). When a user deletes an Author object from the application, I have a few SQLite triggers that run on the delete to remove any books from the database that have a foreign key matching the Author's primary key.

I'm also using a trigger to insert some data when a new item is created.

I can't help but shake the feeling that this might be bad design or lead to some problems down the road I am not thinking of. That said, should I rely on code in my app to handle propagating the deletes like this when the database has the capability built in to handle it?

What say you?

A: 

Code goes in your app.

Triggers are code. The functionality goes in your app. Not in the database.

I think that databases should be used for data, not processing. I think apps should be used for processing, not data.

Database processing features merely muddy the water.

S.Lott
I disagree. There are database mechanisms for ensuring relational integrity and they should be used where appropriate -- like for a cascading delete. As for inserting additional data, it would depend. If done in the app be sure to wrap both inserts in a single transaction.
tvanfosson
@tvanfosson: Declarative referential integrity has some value. Cascading deletes, triggers and what-not generally get out of hand. There always seem to cause more problems than they solve. Some technical and some organizational.
S.Lott
Decalrative referential integrity has huge value. It aids the query optimizer and guarantees that the data is a correct representation of the real world. If you are not willing to learn and understand database coding then leave it to a professional who does ;)
David Aldridge
@David Aldridge: as a data architect, I use declarative RI in every schema because it adds value. How much it helps query optimization is debatable, since indexes help far more than RI.
S.Lott
As an example, it can aid optimisation by indicating that for each row in table A there is guaranteed to be exactly one joining row in table B (where A has a foreign key to B). This allows a better estimate of result cardinality...
David Aldridge
... and in Oracle 11g it can mean that the optimizer can eliminate a table from a query completely.
David Aldridge
@David Aldridge: While your optimization example is good, an index usually matters far more than all the declarative RI in the model. Indeed, in Oracle, the declarative RI often adds indexes because the index matters.
S.Lott
@David Aldridge: my point, however, remains. Code is code, and does not belong in the database. Declarative RI is not code. Triggers are code.
S.Lott
Sure, indexes matter more. But "code does not belong in the database" is an empty statement and means nothing when there are thousands of highly performant, secure, and efficient systems implemented with code-in-database. cont ...
David Aldridge
Mileage with other vendors will vary, but Oracle's PL/SQL is a high performance and secure data manipulation language, and is continually evolving. It may not be the latest bandwagon for young developers to dazzle their employers with, but it'll be around longer than their term of employment.
David Aldridge
@David Aldridge: Code split between database and application is more complex than it needs to be. Code does not belong in the database.
S.Lott
I don't think I understand what "Code split between database and application is more complex than it needs to be" means, and continually chanting "Code does not belong in the database" like a mantra is unpersuasive.
David Aldridge
@David Aldridge: code in two places is more complex than code in one place. I'm trying to simply state my case. Sorry it's unpersuasive. But two places is more complex than one place.
S.Lott
+2  A: 

True. Use the inbuilt capabilities of the database as much as possible. Atleast try and start off like that and only compromise when things really demand so.

Mohit Chakraborty
+1  A: 

I would make use of the database's features to ensure relational integrity, especially with respect to updates/deletes. There are cases where I might use a trigger to insert some additional data (auditing comes to mind), though I would tend to avoid this and insert all of the data from my application. If you are doing multiple inserts, though, make sure to wrap it all in a single transaction so that you don't end up with a partial insert which could lead to loss of relational integrity.

tvanfosson
+1  A: 

I like the idea of using the database's built in functionality (I am not familiar with how it works).. but I would worry if I went back to the code a year from now, would I remember how it worked? (Given the code isn't right in front of me).

I imagine if you add a lot of comments to remind yourself about how it works now, if anything goes wrong in the future, at least you won't need to relearn the database features when you need to go do some debugging.

Lucien
Worse case for this person would be the database cleans house automatically and keeps the data from getting corrupt. Without the trigger, a year later the programmer might forget to clean house in the code and corrupt the database. In otherwords, there is no harm in forgetting about the trigger.
Cory R. King
+1  A: 

You're a few steps ahead of me: I recently learned about how to do that stuff with triggers and I am tempted to use them myself.

Based on the other answers here, it seems like a philosophical choice. It would probably be fine to use either triggers or code, but best to be consistent. So don't use triggers for cascading deletes on one table but then C code for another table.

Since you tagged the question iphone, I think the most important difference would be relative performance of C code versus a trigger. You'd probably have to code both and experiment to determine the difference, if any.

Another thing that comes to mind is that, of all the horror stories that I read on thedailywtf.com, about half of them seem to involve database triggers.

benzado
A: 

Unfortunately SQLite does NOT support on delete cascade etc. From the SQLite documentation:

http://www.sqlite.org/omitted.html

FOREIGN KEY constraints are parsed but are not enforced. However, the equivalent constraint enforcement can be achieved using triggers. The SQLite source tree contains source code and documentation for a C program that will read an SQLite database, analyze the foreign key constraints, and generate appropriate triggers automatically.

There is some support for triggers but it is not complete. Missing subfeatures include FOR EACH STATEMENT triggers (currently all triggers must be FOR EACH ROW), INSTEAD OF triggers on tables (currently INSTEAD OF triggers are only allowed on views), and recursive triggers - triggers that trigger themselves.

Therefore, the only way to code on delete cascade etc using SQLite requires triggers. Kind regards,

unforgiven