35

After having worked at various employers I've noticed a trend of "bad" database design with some of these companies - primarily the exclusion of Foreign Keys Constraints. It has always bugged me that these transactional systems didn't have FK's, which would've promoted referential integrity.

  • Are there any scenarios, in transactional systems, whereby the omission of FK's would be beneficial?

  • Has anyone else experienced this, if so what was the outcome?

  • What should one do if they're presented with this scenario and their asked to maintain/enhance the system?

3
  • 1
    What do you mean no foreign keys? How are rows in one table connected to rows in another? Are you referring to the declaration of foreign keys or to the "fact" of foreign keys, whether declared or otherwise? Commented Aug 22, 2012 at 2:18
  • Yes, "foreign key constraints" ... Commented Aug 22, 2012 at 2:19
  • By "declaration of foreign keys" I assume you mean foreign key constraints Commented Aug 22, 2012 at 2:20

7 Answers 7

53

I cannot think of any scenario where, if two columns have a dependency, they should not have a FK constraint set up between them. Removing referential integrity may certainly speed up database operations but there's a pretty high cost to pay for that.

I have experienced such systems and the usual outcome is corrupted data, in the sense that records exists that shouldn't exist (or vice versa). These are the sort of systems where people believe they're okay because the application takes care of it, not caring that:

  • Every application has to take care of it, rather than one DB server.
  • It only takes one bug, or malignant app, to screw it up for everyone.
  • It is the responsibility of the database to protect itself! That is one of its best features.

As to what you should do, I simply put forward the possible things that can go wrong and how using FKs will prevent that (often with a cost/benefit analysis "skewed" toward my viewpoint, if necessary). Then let the company decide - it is their database, after all.

Sign up to request clarification or add additional context in comments.

3 Comments

And orphaned data that cannot be retrieved nor deleted via the application. Not the end of the world but certainly avoidable. Database design without FK is a mistake.
There is a scenario actually. Think of entities updated in different intervals of time and asynchronously. The Table "BOOK" has a relation with an "AUTHOR", but books and authors are for instance populated by two different Kafka streams, without one knowing about the other.
@Guildenstern70: in that case, I would still have FK constraints, but I would just have a special author "WaitingForKafkaToGetItsDamnActTogether", that books will be assigned to until their real author shows up. And report on this periodically in case the author doesn't appear in a timely manner, for some reason.
15

There is a school of thought that a well-written application does not need referential integrity. If the application does things right, the thinking goes, there's no need for constraints.

Such thinking is akin to not doing defensive programming because if you write the code correctly, you won't have bugs. While true, it simply won't happen. Not using appropriate constraints is asking for data corruption.

As for what you should do, you should encourage the company to add constraints at every opportunity. You don't want to push it to the point of getting in trouble or making a bad name for yourself, but as long as the environment is appropriate, keep pushing for it. Everyone's life will be better in the long run.

1 Comment

Not so much a school of thought as a school of unthinking :-)
7

Personally, I have no problem with a database not having explicit declarations for foreign keys. But, it depends on how the database is being used.

Most of the databases that I work with are relatively static data derived from one or more transactional systems. I am not particularly concerned with rogue updates affecting the database, so an explicit definition of a foreign key relationship is not particularly important.

One thing that I do have is very consistent naming. Basically, every table has a first column called ID, which is exactly how the column is refered to in other tables (or, sometimes with a prefix, when there are multiple relationships between two entities). I also try to insist that every column in such a database has a unique name that describes the attribute (so "CustomerStartDate" is different from "ProductStartDate").

If I were dealing with data that had more "cooks in the pot", then I would want to be more explicit about the foreign key relationships. And, I then I am more willing to have the overhead of foreign key definitions.

This overhead arises in many places. When creating a new table, I may want to use use "create table as" or "select into" and not worry about the particulars of constraints. When running update or insert queries, I may not want the database overhead of checking things that I know are ok. However, I must emphasize that consistent naming greatly increases my confidence that things are ok.

Clearly, my perspective is not one of a DBA but of a practitioner. However, invalid relationships between tables are something I -- or the rest of my team -- almost never has to deal with.

8 Comments

agreed. though, wouldn't "I also try to insist that every column in such a database has a unique name that describes the attribute (so "CustomerStartDate" is different from "ProductStartDate")." be a non-issue if you use aliases for your tables in queries? e.g.: select a.startdate, b.startdate from foos a join bars b on a.id = b.aid
@Curiosity . . . Clearly, many people disagree with my naming conventions. However, they are very important to me. Something like "aid" to me exists as a name, and it should be named the same thing everywhere -- where it is defined and where it is used.
While you may not be concerned about rogue updates, if you're human, you make mistakes. If you're not concerned about foreign keys, then you've been lucky thusfar. One day, that will change and you'll insist on foreign keys from that day forward.
@wadesworld . . . I think you missed my point. I often work with databases derived from other systems. I have confidence in the underlying systems, and don't need to reimplement the checks. Not all databases are transactional systems with random inserts and updates.
DBA's on the other systems can make mistakes too. By not protecting yourself, you're just asking for trouble at some point, in my opinion. But, it's certainly your decision. All I'm saying is that most people who are adamant about foreign key usage can tell you of a data corruption issue that "couldn't possibly happen," but did.
|
3

In an OLTP database, the only reason I can think of is if you care about performance more than data integrity. Enforcing a FK when row is inserted to the child table requires an index seek on the parent table and I can imagine there may be extreme situations where even this relatively quick index seek is too much. For example, some kind of very intensive logging where you can live with incorrect log entries and the application doing the writing is simple and unlikely to have bugs.

That being said, if you can live with corrupt data, you can probably live without a database in the first place.

Comments

3

As long as there's a single point of entry into the database it ultimately doesn't matter which "layer" is maintaining referential integrity. Using the "built-in layer" of foreign key constraints seems to make the most sense, but if you have a rock solid service layer responsible for the same thing then it has freedom to break the rules if necessary.

Personally I use foreign key constraints and engineer my apps so they don't have to break the rules. Relational data with guaranteed referential integrity is just easier to work with.

The performance gained is probably equivalent to the performance lost from having to maintain integrity outside of the db.

1 Comment

"a rock solid service layer"? Let me know when you find such a beast :-)
0

Defensive Programming withot foreign keys works if you primarily use stored procedures and every application uses those stored procedures, instead of writing their own queries. Then you can control it quite easily and more flexible than the standard foreign keys.

One situation I can think of off the top of my head where foreign key constraints are not readily usable is a permissions module where permissions can be applied per user or per group, determined by a Boolean. So some of the records in the permissions table have a user id and others have a group id. If you still wanted foreign key constraints, you would have to have two different fields for the same mutally exclusive information and allow them to be null. Meaning adding another constraint saying that one is allowed to be null but they can't both be null, as well as a combination of 3 fields must be unique instead of a combination of 2 fields (user/group id and permission id). And the alternative is two separate tables containing the same data, meaning maintaining both tables separately.

But perhaps in that scenario, it's best to separate the data. Anything where you need the same field to connect to different tables based on other data in that record, you cannot use foreign field constraints, and it becomes best to keep the constraints in the stored procedures and views instead.

Comments

-1

I recently had a case where i had to remove my foreign key constraints. I had to work with transactions and rollback/commits because of many dependencies and the DB did not support dirty reads for the constraint or the DEFER keyword in adding the constraint. Herefor i decided to remove the FK constraints and pay more attention to keep the database integrety programatticaly.

1 Comment

This does not really answer the question. If you have a different question, you can ask it by clicking Ask Question. To get notified when this question gets new answers, you can follow this question. Once you have enough reputation, you can also add a bounty to draw more attention to this question. - From Review

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.