许多人只是在应用程序代码中强制执行所有这些规则。也就是说,它们“简单地”不会插入错误的数据。当然,这是非常脆弱的,并且始终依赖于编写完美的应用程序代码。所以我们希望数据库强制执行约束,这样就永远不会插入错误的数据。
CREATE TABLE A (
id INT PRIMARY KEY,
type CHAR(1) NOT NULL,
unique key (id, type)
);
CREATE TABLE B (
id INT PRIMARY KEY,
type CHAR(1) NOT NULL DEFAULT 'B',
FOREIGN KEY (id, type) REFERENCES A(id, type)
);
如果您可以强制 B.type 始终为“B”(检查约束、触发器或引用单行查找表),那么它当然可以引用 A 中 type='B' 的父行。并在表 C 和 D 中执行类似的操作,因此 A 的每一行只能被一个子类型表中的一行引用。
也就是说,如果 A.type 在给定行上是“B”,而 C.type 只能是“C”,则 C 的任何行都不能引用 A.type 为“B”的任何行。
现在如果你想让表 Z 引用 B 或 C 而不是 D,你可以通过 id和type 来引用,所以 Z 也有自己的 type 列。您可以使用查找表来限制 Z.type:
CREATE TABLE Ztypes (
type CHAR(1) PRIMARY KEY
);
INSERT INTO Ztypes VALUES ('B'), ('C');
CREATE TABLE Z (
id INT PRIMARY KEY,
Aid INT NOT NULL,
type CHAR(1) NOT NULL,
FOREIGN KEY (Aid, type) REFERENCES A(id, type),
FOREIGN KEY (type) REFERENCES Ztypes(type)
);