Permalink
Browse files

Add generic_foreign_keys section

Fixes #2
  • Loading branch information...
alexpdp7 committed Dec 2, 2018
1 parent 474a815 commit 39605f74e170fbf0a09a2176489127ddfcf6316b
Showing with 40 additions and 0 deletions.
  1. +1 −0 README.md
  2. +39 −0 database_design/patterns_antipatterns/generic_foreign_keys.md
@@ -37,6 +37,7 @@ This is an index of the topics we believe are relevant to the discussion. Feel f
* [Subtyping](database_design/patterns_antipatterns/subtyping.md)
* [BLOB or not](database_design/patterns_antipatterns/blob_or_not.md)
* "Extensible" schemas, JSON/XML
* [Generic foreign keys](database_design/patterns_antipatterns/generic_foreign_keys.md)
* [Don't serialize](database_design/patterns_antipatterns/dont_serialize.md)
* [Don't delete](database_design/patterns_antipatterns/dont_delete.md)
* Configuration tables
@@ -0,0 +1,39 @@
# Generic foreign keys

Some ORMs and frameworks allow defining special foreign keys which reference multiple different tables. They use schemas such as:

```
CREATE TABLE users (
id serial primary key,
...
);
CREATE TABLE posts (
id serial primary key,
...
);
CREATE TABLE comments (
id serial primary key,
commented_object_id integer not null,
commented_object_type enum(users|posts),
...
);
```

This sample schema would allow creating `comments` on `users` *and* `posts`.

Typically, these work more or less transparently when using your ORM, but often they have limitations.

First and foremost, referential integrity tends to be lost. Unless they spend significant effort, dangling references can be created and deletion/updates on referenced tables won't enable [cascade behaviors](dont_fear_the_cascade.md).

Similarly, making queries that join tables referenced by those kinds of keys are significantly harder, requiring contortions such as:

```
SELECT *
FROM comments
JOIN posts ON comments.commented_object_id = posts.id AND comments.commented_object_type = posts
JOIN users ON comments.commented_object_id = users.id and comments.commented_object_type = users
```

We advise not using this kind of functionalities, but use approaches which fit better the relational model such as [subtyping](subtyping.md).

0 comments on commit 39605f7

Please sign in to comment.