You should always enforce referential integrity by using “normal” FOREIGN KEYs.
In a nutshell, FOREIGN KEYs have the following advantages:
- They are already implemented within the DBMS.
- They are declarative, self-documenting and “obvious”.
- They cannot be bypassed (unless explicitly disabled or dropped).
- They are correct.
- They are fast.
- They support cascading referential actions (such as ON DELETE CASCADE).
- The DBMS knows the data is related, allowing it to find a better query plan in some cases .
- If you are using an ORM tool, it can automatically generate references between objects.
And here are the corresponding disadvantages of enforcing referential integrity in the application code:
- You are duplicating the work that has already been done.
- It’s imperative, probably “buried” deep in your application source code, and harder to maintain.
- A single client application that has a bug can break the referential integrity (and corrupt the data).
- You are likely to implement them incorrectly in your application code. It looks simple from the outset, but in a concurrent environment, it is easy to introduce race conditions.
- Even if you have implemented them correctly, you probably used some form of locking to avoid race conditions, which is likely to be slower / less scalable than specially optimized FKs built into the DBMS.
- You have to implement cascading yourself.
- The DBMS doesn’t know the data is related, which may produce sub-optimal query plan.
- You may need to do more manual work in your ORM tool of choice.
Is there a name for this?
Not that I know of. I heard a term “generic FKs” being used, but that’s probably not universal.
Is it good practice?
No (see above).
Any performance considerations?
Yes (see above).