Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Should we use foreign-key constraints when persisting Domain Models?

A while ago I had a discussion with my colleagues about the persistence of Domain Models and whether we should enforce foreign-key constraints at the database level.

My first reaction was that the very use of a relational database implied the enforcement of such constraints, but some argued that the database should be seen as nothing but a persistence mechanism and therefore we should avoid placing any business logic in it. We ended up by not using foreign-key constraints.

Here is my question (I hope it is not too generic): is it considered good practice to enforce key constraints in theses cases?

like image 378
Saulo Silva Avatar asked Jul 02 '09 19:07

Saulo Silva


2 Answers

Enforce constraints, but do NOT rely on them in your business logic

  • No business logic on the database: I agree with the principle. And if your non-SQL business code relies on the database constraints to check your database consistency, then you should rethink your business logic.
  • There is nothing wrong of having database constraints in addition to your business logic. Especially because things like referential integrity with FOREIGN KEYs and other UNIQUE constraints are easy to do and RDBMS are doing that job for you very efficiently without much maintenance.
  • Will you not use indices on the database too, because it is not purely persistency related?
  • Finding and fixing software bug may take you some time, but you definitely do not want to spend even more time cleaning up or (worse) loosing some data, just because you saved yourself a trouble of writing one-line script for a FK. Really: your get something for free here and your reject it?
  • [EDIT-1]: can you guarantee that the data in your database would be managed ONLY via your application? There always seem to be exceptions, mostly by power-users, who do sometimes (very rarely :-) make mistakes and execute some SQL statements to clean-up your code, update statuses (to invalid values because of typos) etc.
  • [EDIT-2]: Building domain driven model is not an excuse not to hire a good DB admin. Using ORM is not an excuse not to hire good DB developer.

But if you and your team are able to write bug-free software and handle all possible exception scenarios in your code (including hardware/network/dummy-user/programmer-error failures), then "Hei, why bother with redundant FK constraints...." - -teaser-

like image 67
van Avatar answered Oct 18 '22 10:10

van


If you want to follow the Domain Driven Design paradigm, then the answer would be yes for anything within an Aggregate, and no for any cross-Aggregate links.

In nearly all cases, you want anything under the Aggregate Root to be deleted when the Root itself is deleted, and so having foreign keys that represent this, with cascading deletes, allow you to achieve this at the database level. You could also have your Repositories do the cascading deletes themselves if you didn't want to do it at a DB level, but the point still stands that Aggregate children should not exist without the Root.

For cross-Aggregate concerns, you'll probably be dealing with business decisions as to what should happen when one or the other is removed. Often you'll want to deal with this asynchronously to allow for scalability, and so your domain model ends up being eventually consistent. Therefore, it doesn't make sense in these cases to enforce foreign keys as there'll be a window of time where one or the other key may not exist.

Hope that helps! And for more info, definitely check out Evans' book on Domain Driven Design - and the many links around the web too.

like image 28
Michael Hart Avatar answered Oct 18 '22 08:10

Michael Hart