views:

165

answers:

6

I'm working on an old web application my company uses to create surveys. I looked at the database schema through the mysql command prompt and thought the tables looked pretty solid. Though I'm not a DB guru I'm well versed in the theory behind it (having taken a few database design courses in my software engineering program).

That being said, I dumped the create statements into an SQL file and imported them in MySQL Workbench and saw that they make no use of any "actual" foreign keys. They'll store another table's primary key like you would with a FK but they don't declare it as one.

So seeing how their DB is designed the way I would through what I know (minus the FK issue) I'm left wondering that maybe there's a reason behind it. Is this a case of lazy programming or could you get some performance gains by doing all the error check programmatically?

In case you'd like an example they basically have Surveys and a survey has a series of Questions. A question is part of a survey so it holds it's PK in a column. That's pretty much it but they use it everywhere.

I'd appreciate any insight :) (I understand that this question might not have a right/wrong answer but I'm looking more for some information on why they would do this as this system has been pretty solid ever since we started using it so I'm led to believe that these guys knew what they were doing)

+4  A: 

MySQL only supports the defining of actual foreign key relationships on InnoDB tables, maybe yours are MyISAM, or something else?

More important is that the proper columns have indices defined on them (so the ones holding the PK of another table should be indexed). This is also possible in MyISAM.

Lex
+7  A: 

The original developers might have opted to use MyISAM or any other storage engine that does not support foreign key constraints.

Daniel Vassallo
That's exactly what it is. I might be able to design something on paper but I'm definitely lacking in the practice department. Thanks a lot guys :)
Gazillion
Just as a side-note, MySQL has been supporting foreign keys for InnoDB since version 3.23.44. Source: http://en.wikipedia.org/wiki/MySQL#Future_releases
Daniel Vassallo
I use MySQL workbench to create my schema and then export my statements. I'll always pick InnoDB as my storage engine hence why I wasn't aware that MyISAM didn't support FKs at all.
Gazillion
And if you want to use the MySQL specific full-text search capabilities you have to use MyISAM, it doesn't work with InnoDB (or any other table type for that matter)...
wimvds
And this is as good a reason not to use MySQL as any other I've seen.
Andrew Aylett
A: 

You don't really have to use foreign keys.

If you don't have them, data might became inconsistent and you won't be able to use cascade deletes and updates.

If you have them you might loose some of the users data due to the bug in your SQL statements that happens because of schema changes.

Some prefer to have them, some prefer life without them. There's no real advantages in either case.

vava
I would say that data consistency is a real advantage.
simon
@simon I would agree
meagar
@simon, not really. You'll most likely will just have additional rows lying around that won't bother you much as they will be invisible to most of the queries. On the other hand those hidden rows might have some information that is critical to the user.
vava
@vava, but it's not just about enforcing deletion on abandoned child objects. Enforcing data consistency with foreign keys prevents also many mistakes, like changing the keys to referenced objects to nonexistent values (which are the kind of mistakes often impossible or very difficult to correct after the accident). And if you think that some information should be stored for historical purposes, there are better means than leaving out the foreign keys.
simon
@simon, it also saves you from trouble when you have to make circular references. I have lived with them for 5 years and without them for 2 and frankly I see no difference. Except I don't have to think in what order should I put data in tables so it won't blow up in my face.
vava
+1  A: 

On uber large databases (the type that Teradata support) you find that they don't use Foreign keys. The reason is performance. Every time you write out to the database, which is often enough in a data warehouse you have the added overhead of having to check all the fk's on a table. If you already know it to be true, what's the point.

Good design on a small db would just mean you put them in, but there are performance gains to be had by leaving them out.

pms1969
Thanks. This is something I was wondering. I think their database has a small enough number of tables that keeping track of "FKs" would be easy enough.
Gazillion
A: 

Here is a real life instance where I'm not using a foreign key.

I needed a way to store a parent child relationship where the child may not exist, and the child is an abstract class. Since the child could be of a few types, I use one field to name the type of the child and one field to list the id of the child. The application handles most of the logic.

I'm not sure if this was the best design decision, but it was the best I could come up with under the deadline. It's been working well so far!

Peter Di Cecco
+1  A: 

As general points; keys speed up reads (if they are applicable to the read taking place they help the optimizer) and slow down writes (because they add overhead to the tables).

In the vast majority of cases the improvement of speed for reading and maintenance of referential integrity outweighs the minor overhead they add to writes.

This distinction has been blurred by cacheing, mirroring etc as so many reads on the very big sites don't actually hit the 'live' database - but this is not very relevant unless you are working for Amazon, Twitter or the like.

amelvin