使用 SQL 约束可以达到的最佳效果FOREIGN KEY
是确保每个抵押类型在每个子类型表中最多出现一次,如果愿意的话,是一对零或一关系。{ ID , type }
强制执行此约束的一种方法是在整个架构中使用两列复合键,并允许type
在子表约束中进行测试。这是使用两种抵押子类型的粗略草图(大括号表示没有隐含顺序的列表):
Mortgages { mortgage_ID , mortgage_type }
KEY { mortgage_ID }
KEY { mortgage_ID , mortgage_type }
CONSTRAINT mortgage_type = 'Tracker'
OR mortgage_type = 'Fixed'
FixedRateMortgages { mortgage_ID , mortgage_type , fixed_rate }
KEY { mortgage_ID , mortgage_type }
FOREIGN KEY { mortgage_ID , mortgage_type } REFERENCES Mortgages
CONSTRAINT mortgage_type = 'Fixed';
FixedRateMortgages { mortgage_ID , mortgage_type , base_rate , track_rate }
KEY { mortgage_ID , mortgage_type }
FOREIGN KEY { mortgage_ID , mortgage_type } REFERENCES Mortgages
CONSTRAINT mortgage_type = 'Tracker';
Clients { client_ID }
KEY { client_ID } ;
Agreements { mortgage_ID , mortgage_type , client_ID }
KEY { mortgage_ID , mortgage_type , client_ID }
FOREIGN KEY { mortgage_ID , mortgage_type } REFERENCES Mortgages
FOREIGN KEY { client_ID } REFERENCES Client;
您没有指定 SQL 产品。可以在标准 SQL-92 中使用声明为封装每个子类型表逻辑的“分布式”的CREATE ASSERTION
约束来维护严格的一对一引用完整性。DEFERRABLE INITIALLY DEFERRED
然后,SQL 语句可以在事务中推迟ASSERTION
s,修改引用和引用的表,然后重新应用ASSERTION
s(或通过提交事务自动执行此操作)。遗憾的是,现实生活中没有支持CREATE ASSERTION
. 有一些解决方法取决于供应商,例如触发器、从行级CHECK
约束调用的 SQL 函数中的表表达式、撤销表的写权限然后强制用户通过确保引用完整性的 CRUD 过程更新表等。
也就是说,在 SQL 中,一对零或一关系通常是可以接受的,并且确实这样做可能有好处,例如使数据库约束更易于编写(因此错误更少),不强迫用户的灵活性使用一套程序等