The SitePoint Forums have moved.

You can now find them here.
This forum is now closed to new posts, but you can browse existing content.
You can find out more information about the move and how to open a new account (if necessary) here.
If you get stuck you can get support by emailing forums@sitepoint.com

If this is your first visit, be sure to
check out the FAQ by clicking the
link above. You may have to register
before you can post: click the register link above to proceed. To start viewing messages,
select the forum that you want to visit from the selection below.

It seems to me like this is using the database for business logic. If that's true, then which is the better location for keeping referential integrity between a primary key on one table and a foreign key on another? PHP or MySQL? Also, could DB views be considered business logic? How do you decide how much to have the database do, and how much to do yourself?

MySQL is a Relational Database. It's OK for the database to know about table relations. I started setting up all my tables like this with foreign key constraints about a year ago, and have never looked back. Anything that makes my life easier and eliminates orphaned records with no upkeep is a win in my book, whether or not it's the "right" way to do it.

You can't do that in all MySQL databases, so you should have that in your code.
If the database you plan to use can use foreign keys, and you plan never to change that database to something else, then you can put that logic in the database.

I use them as well. That way keeping the data integrity is not dependent on my code and a lot easier to achieve. If I make an error in my code and try to do something to the data which isn't allowed I get a nice error/warning from the database.

In the same way that you set the data field type to a certain type (say VARCHAR or INT), foreign key restrictions are a way to keep the data model rules close to where they belong, in the database.

It doesn't hurt to define the foreign keys (even if mySQL using ISAM doesn't support it). It provides an additional level of validation where it is supported and if you know your database supports it then it makes some database calls much simpler to implement.

It seems to me like this is using the database for business logic. If that's true, then which is the better location for keeping referential integrity between a primary key on one table and a foreign key on another? PHP or MySQL?

anything to do with the correctness of the data should be handled by the database engine, if at all possible

there are instances where you cannot implement certain rules in the database, and then it would be okay to use application logic

but if the database can enforce something, you really should let the database enforce it

and a business rule like "don't have any books loaned out to employees that don't exist" is a great example of a business rule that could and should be enforced by the database

you declare it in a few lines of SQL, and you're done

do you really want to bloat the app with the same logic? in all the places where the app touches those tables?

Originally Posted by allspiritseve

Also, could DB views be considered business logic? How do you decide how much to have the database do, and how much to do yourself?

views are something else, but yeah, i guess they could be interpreted as business rules -- for example, don't show ~everybody~ the contents of the employee salary column, just authorized users in HR

again, do you really want to bloat the app with the same logic? in all the places where the app touches those tables?

which is the better location for keeping referential integrity between a primary key on one table and a foreign key on another? PHP or MySQL?
Integrity between database tables belongs naturally to database, not outside to application. So correct answer is PostgreSQL, Firebird, SQL Server or any other database.

could DB views be considered business logic
Yes.

How do you decide how much to have the database do, and how much to do yourself?
It depends. For example, constraints are to be checked on application level to eliminate unavailing round-trips with wrong data for INSERT or UPDATE. But triggers are fine and also stored procedures for some business logic.

Why not? Isn't it more important to check that a query satisfies specified requirements before submitting than to assume the database will check it for you (at least from the end-user's perspective)? That way, you can give the user more fine-grained feedback than just "insert failed", because you know exactly why the query failed... no borrower was selected when you tried to borrow a book.

the application is seldom the only way that data gets into the database

In my opinion, the database's contraints should be less than or equal to the contraints in the app. If your database is more selective than your app, then you get failed queries and the user doesn't know why, because the app let that data through. The database should be the last line of defense. I'm not arguing against keeping the constraints in the db, just saying that they're duplicating constraints in the app that I feel are more important because they allow the user to retry submitting. A failed query doesn't do that.

surely you don't just print "query error" but actually translate the error code that the database issues...

Actually I check in my app and make sure everything is valid before the query's even submitted. If the data isn't valid, I give the user helpful feedback. If the data is valid and the query fails, it's due to a bug, not bad data, so I tell the user such and ship off an email telling me to FIX IT!

Actually I check in my app and make sure everything is valid before the query's even submitted. If the data isn't valid, I give the user helpful feedback. If the data is valid and the query fails, it's due to a bug, not bad data, so I tell the user such and ship off an email telling me to FIX IT!

I think the point is that you can take some of the validation out and let the DB do it's job. Most people see a DB error as a bug, but it's not always the case.

For example, when inserting possibly duplicate key rows, check for a duplicate row error, and you could throw it as an exception and let the application then handle how it affects the user -- it doesn't have to translate to a db error page. It's more efficient than running an extra select first and then inserting.

Everything you can offload from the application into the database will make the processing more efficient. Also the more info you give the database about the data relationships the more efficiently it can handle the requests you do give to it.

Everything you can offload from the application into the database will make the processing more efficient. Also the more info you give the database about the data relationships the more efficiently it can handle the requests you do give to it.

I would take that statement with a grain of salt. Offloading everything possible from application to database is hardly an ideal design choice. This tends to make the database slower and consequently the application less efficient. That is why I usually limit the amount of processing ported to database to those that are strictly about data, tables, and relationships. Stored procedure, for example, allow you to move a big chunk of processing from application to the database. However, if you abuse the feature and move as much logic to database as possible you end up with a terribly inefficient system that is not only slow but also nightmarish to maintain.

As for why Foreign Keys: It’s important to remember that a database can have multiple access points. Several disparate applications could be running off the same database and in rare occasions a DBA could directly operate on the database. Having data integrity constrains like foreign key directly in database come immensely handy in these situations.

Itís important to remember that a database can have multiple access points. Several disparate applications could be running off the same database and in rare occasions a DBA could directly operate on the database. Having data integrity constrains like foreign key directly in database come immensely handy in these situations.

That I can completely understand. I don't think foreign key constraints are a replacement for proper input validation, though.

What you are doing by providing all that info to the database is to give it more information about the data the database contains so that it can be MORE efficient at processing the data in the database. Not giving the database that information means that the database has less information about the data and therefore may not chose the most effective way of processing it. Supplying the database with more info about the data can only make processing faster - not slower. At worst it will make no difference.

Just who decides on, sets and adjusts the business rules may influence whether you want delegate this power to the rdbms from the get go.

I suppose as a programmer controlling the actions of a dba (or you are one and the same) does the choice of whether to hard wire these decisions into the db balance on pretty variable management whims?

Actually I check in my app and make sure everything is valid before the query's even submitted. If the data isn't valid, I give the user helpful feedback. If the data is valid and the query fails, it's due to a bug, not bad data, so I tell the user such and ship off an email telling me to FIX IT!

Not necessarily unless you lock tables as part of your validation process. While you are doing the checks another process could slip in and modify the database thus invalidating your original checks.

Not necessarily unless you lock tables as part of your validation process. While you are doing the checks another process could slip in and modify the database thus invalidating your original checks.

My validation doesn't hinge on checking the database to determine if the data is valid. That obviously would become more important the more people you have editing the same data, but the majority of the time validation should be able to catch errors before any queries are made. If it's possible for me to check it before I make the query, I would prefer that 100% of the time over letting the database do the validation because then I can give fine-grained feedback back to the user. That isn't to say having the database do a second check isn't valid... it's just unnecessary in a lot of cases.

My validation doesn't hinge on checking the database to determine if the data is valid. That obviously would become more important the more people you have editing the same data, but the majority of the time validation should be able to catch errors before any queries are made.

Surely you have some integrity constraints? I find it common to check whether a user id is valid before inserting a comment row or some other record in the database. I find this might happen more often than people realize, and while your validation server-side might pass when you do the check, by the time you insert the record in the database it's possible that the user was deleted or some other instance causes your previously valid record to become invalid. This is why I find it completely necessary to use database validation and integrity constraints. With any decent sized traffic, concurrent connections have to be expected. MyISAM doesn't currently support relationships which (to me) makes it unusable as a reliable database source. Just my two cents.