Can a foreign key have a constant instead of a field name? Relate FK to STI subclass
Asked Answered
D

1

9

Setup

So here's a scenario which I'm finding is rather common once you decide to play with STI (Single Table Inheritance).

You have some base type with various subtypes.

  • Person < (Teacher,Student,Staff,etc)
  • User < (Member,Admin)
  • Member < (Buyer,Seller)
  • Vehicle < (Car,Boat,Plane)
  • etc.

There are two major approaches to modelling that in the database:

  • Single Table Inheritance
    • One big table with a type field and a bunch of nullable fields
  • Class Table Inheritance
    • One table per type with shared PK (FK'd from the children to the parent)

While there are several issues with STI, I do like how it manages to cut down on the number of joins you have to make, as well as some of the support in frameworks like Rails, but I am running into an issue on how to relate subclass-specific tables.

For example:

  • Certifications should only reference Teacher-Persons
  • Profiles should only reference Member-Users
  • WingInformation should be not be related to a car or boat (unless you are Batman maybe)
  • Advertisements are owned by Seller-Members not Buyer-Members

With CTI, these relationships are trivial - just slap a Foreign Key on the related table and you're done:

ALTER TABLE advertisements
 ADD FOREIGN KEY (seller_id) REFERENCES sellers (id)

But with STI, the similar thing wouldn't capture the subtype restriction.

ALTER TABLE advertisements
  ADD FOREIGN KEY (seller_id) REFERENCES members (id)

What I would like to see is something like:

* Does not work in most (all?) databases *
ALTER TABLE advertisements
  ADD FOREIGN KEY (seller_id, 'seller') REFERENCES members (id, type)

All I have been able to find is a dirty hack requiring adding a computed column to the related table:

ALTER TABLE advertisements
  ADD seller_type VARCHAR(20) NOT NULL DEFAULT 'seller'
ALTER TABLE advertisements
  FOREIGN KEY (seller_id, seller-type) REFERENCES members (id, type)

This strikes me as odd (not to mention inelegant).

The real questions

Is there a RDBMS out there which will allow me to do this?

Is there a reason why this isn't even possible?

Is this just one more reason why NOT to use STI except in the most trivial of cases?

Dodona answered 25/11, 2012 at 13:40 Comment(0)
B
5

There's no standard way to declare a constant in the foreign key declaration. You have to name columns.

But you could force the column to have a fixed value, using one of the following methods:

  • Computed column

  • CHECK constraint

  • Trigger before INSERT/UPDATE to overwrite any user-supplied value with the default value.

Bazaar answered 25/11, 2012 at 18:36 Comment(2)
Thanks @Bill and yeah, I've seen the suggestion of a computed or check-and-trigger column before (since there isn't a standard for what I want). Do you know of any engines that allow the syntax I mentioned (even in some non-standard way).Dodona
Sorry, I don't know of any.Bazaar

© 2022 - 2024 — McMap. All rights reserved.