Некоторые люди используют для этого дизайн под названием Полиморфные ассоциации, позволяющий vehicle_id
содержать значение, которое существует либо в car
, либо motor
таблицах. Затем добавьте vehicle_type
, который называет таблицу, на которую ссылается данная строка в t1
.
Проблема в том, что вы не можете объявить реальное ограничение внешнего ключа SQL, если вы сделаете это. В SQL нет поддержки внешнего ключа с несколькими ссылочными целями. Есть и другие проблемы, но отсутствие ссылочной целостности уже нарушает правила.
Лучший дизайн - заимствовать концепцию из ОО дизайна общего супертипа как car
, так и motor
:
CREATE TABLE Identifiable (
id SERIAL PRIMARY KEY
);
Затем сделайте t1
ссылку на эту таблицу супертипа:
CREATE TABLE t1 (
vehicle_id INTEGER NOT NULL,
FOREIGN KEY (vehicle_id) REFERENCES identifiable(id)
...
);
А также сделайте так, чтобы подтипы ссылались на родительский супертип. Обратите внимание, что первичным ключом подтипов является , а не с автоинкрементом. Родительский супертип заботится о выделении нового значения id, а потомки ссылаются только на это значение.
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)
...
);
Теперь вы можете иметь истинную ссылочную целостность, но также поддерживать несколько таблиц подтипов со своими собственными атрибутами.
Ответ @Quassnoi также показывает способ применения непересекающихся подтипов . То есть вы хотите запретить ссылкам на car
и motor
одну и ту же строку в их родительской таблице супертипов. Когда я делаю это, я использую первичный ключ с одним столбцом для Identifiable.id
, но также объявляю ключ UNIQUE
вместо Identifiable.(id, type)
. Внешние ключи в car
и motor
могут ссылаться на уникальный ключ из двух столбцов вместо первичного ключа.