The design you're describing is called exclusive arcs. Yes, it's a pretty fragile design and even fails some rules of normalization.
Here's an alternative:
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)
With this design, each row in Main_Table
must reference one row in T0
.
Likewise, each row in T0
can be the parent of only one row in T1
, T2
, or T3
.
This is a way to implement Class Table Inheritance and Polymorphic Associations without breaking referential integrity.
Main_Table is attempting to be a payer
table, which could reference either an
individual user (T1), a group of
individual users (T2), or a group of
groups (T3).
Right, so think of this in terms of object-oriented design. If you had three classes that could function as a recipient of payments, you'd create a interface called Payable
or something, so that each you could rely on typing those objects. All Payable
objects must have a sendPayment()
method for instance. In some OO languages, the interface is a superclass and is called an abstract class or a pure virtual class.
The T0
table functions as a common type for each of the child tables T1
, T2
, and T3
. When Main_Table
has a foreign key to T0
, it's like saying Main_Table
must have a reference to some entity that is Payable
, but any object descending from that superclass is okay to use.
The type
column is just a trick to make sure that a given T0.id
can be referenced only by one subclass table at a time. It's kind of optional, if you can rely on your application logic to insert a given child row into only one of the subclass tables.
Also see the section on Polymorphic Associations in my presentation "SQL Antipatterns Strike Back."