你所描述的被称为独家弧设计。是的,这是一个非常脆弱的设计,甚至没有规范化的规则。
这里有一个选择:
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)的,或一组 基(T3) 。
对,所以在面向对象的设计方面想一想。如果您有三个可用作付款收款人的班级,您可以创建一个界面或称为Payable
,这样您就可以依靠输入这些对象。例如,所有Payable
对象都必须具有sendPayment()
方法。在某些OO语言中,接口是超类,称为抽象类或纯虚拟类。
T0
表作为每个子表T1
,T2
和T3
的通用类型。当Main_Table
有一个到T0
的外键,就像是说Main_Table
必须对某个实体的引用是Payable
,但是任何从该超类下降的对象都可以使用。
type
列只是确保给定的T0.id
一次只能由一个子类表引用的技巧。如果你可以依靠你的应用程序逻辑将一个给定的子行插入到其中一个子类表中,那么它是可选的。
也看到在我的演讲多态关联节 “SQL Antipatterns Strike Back。”
它气味不好的设计。你可以更多地了解数据是什么以及为什么你想以这种方式来关联它? – spender 2009-09-11 01:25:57
看起来你试图创建某种有条件的外键。正如提到的那样,对你想要完成的事情的感觉将帮助我们确定最佳方法。 – 2009-09-11 01:30:15