Some people use a design called Polymorphic Associations to do this, allowing vehicle_id
to contain a value that exists either in car
or motor
tables. Then add a vehicle_type
that names the table which the given row in t1
references.
The trouble is that you can't declare a real SQL foreign key constraint if you do this. There's no support in SQL for a foreign key that has multiple reference targets. There are other problems, too, but the lack of referential integrity is already a deal-breaker.
A better design is to borrow a concept from OO design of a common supertype of both car
and motor
:
CREATE TABLE Identifiable (
id SERIAL PRIMARY KEY
);
Then make t1
reference this super-type table:
CREATE TABLE t1 (
vehicle_id INTEGER NOT NULL,
FOREIGN KEY (vehicle_id) REFERENCES identifiable(id)
...
);
And also make the sub-types reference their parent supertype. Note that the primary key of the sub-types is not auto-incrementing. The parent supertype takes care of allocating a new id value, and the children only reference that value.
CREATE TABLE car (
id INTEGER NOT NULL,
FOREIGN KEY (id) REFERENCES identifiable(id)
...
);
CREATE TABLE motor (
id INTEGER NOT NULL,
FOREIGN KEY (id) REFERENCES identifiable(id)
...
);
Now you can have true referential integrity, but also support multiple subtype tables with their own attributes.
The answer by @Quassnoi also shows a method to enforce disjoint subtypes. That is, you want to prevent both car
and motor
from referencing the same row in their parent supertype table. When I do this, I use a single-column primary key for Identifiable.id
but also declare a UNIQUE
key over Identifiable.(id, type)
. The foreign keys in car
and motor
can reference the two-column unique key instead of the primary key.