Описываемый вами дизайн называется эксклюзивные дуги . Да, это довольно хрупкий дизайн и даже не соответствует некоторым правилам нормализации.
Вот альтернатива:
Main_Table
id UNIQUEIDENTIFIER
t_id INT NOT NULL
FOREIGN KEY (t_id) REFERENCES T0 (id)
T0
id UNIQUEIDENTIFIER
type INT NOT NULL CHECK (type IN (1,2,3))
UNIQUE KEY (id, type)
T1
id INT
type INT NOT NULL CHECK (type = 1)
name VARCHAR(255)
FOREIGN KEY (id, type) REFERENCES T0 (id, type)
T2
id INT
type INT NOT NULL CHECK (type = 2)
name VARCHAR(255)
FOREIGN KEY (id, type) REFERENCES T0 (id, type)
T3
id INT
type INT NOT NULL CHECK (type = 3)
name VARCHAR(255)
FOREIGN KEY (id, type) REFERENCES T0 (id, type)
При таком дизайне каждая строка в Main_Table
должна ссылаться на одну строку в T0
.
Аналогично, каждая строка в T0
может быть родительской только для одной строки в T1
, T2
или T3
.
Это способ реализации наследования таблиц классов и полиморфных ассоциаций без нарушения ссылочной целостности.
Main_Table пытается быть плательщиком
таблица, которая может ссылаться либо на
индивидуальный пользователь (T1), группа
отдельные пользователи (T2) или группа
группы (Т3).
Правильно, так что подумайте об этом с точки зрения объектно-ориентированного дизайна. Если бы у вас было три класса, которые могли бы функционировать в качестве получателя платежей, вы бы создали интерфейс с именем Payable
или что-то подобное, чтобы каждый из них мог полагаться на ввод этих объектов. Например, все объекты Payable
должны иметь метод sendPayment()
. В некоторых языках ОО интерфейс является суперклассом и называется абстрактный класс или чистый виртуальный класс .
Таблица T0
функционирует как общий тип для каждой из дочерних таблиц T1
, T2
и T3
. Когда Main_Table
имеет внешний ключ для T0
, это все равно что сказать, что Main_Table
должен иметь ссылку на некоторую сущность, которая является Payable
, но любой объект, происходящий из этого суперкласса, можно использовать.
Столбец type
- это всего лишь хитрость, позволяющая убедиться, что на данный T0.id
может ссылаться только одна таблица подкласса за раз. Это не обязательно, если вы можете положиться на логику своего приложения, чтобы вставить данную дочернюю строку только в одну из таблиц подкласса.
См. Также раздел Полиморфные ассоциации в моей презентации " SQL Antipatterns Strike Back ."