我对我遇到的设计问题有疑问......
表A有子类型B和C.表A有一个属性类型,告诉类型是B还是C.B和C的共同属性在A中。
问题是B没有额外的属性.B所需的所有属性都已经在A中。但是,C还有其他属性。
如果我只创建表A和C,它是否是可接受的解决方案?? ...提取B的实体我将通过表A中的type属性进行查询
你能推荐任何材料吗?
我还有另一个困惑,其中表A有B,C,D的子类型。表Z有一列需要主要ID为B或C但不是D。
我想添加A的主id列作为Z列的外键引用,然后触发以确保id不是D ...
任何人都可以发表评论吗?
谢谢!
答案 0 :(得分:2)
许多人只是在应用程序代码中强制执行所有这些规则。也就是说,他们“只是”不插入错误的数据。当然这非常脆弱,并且总是依赖于编写完美的应用程序代码。因此,我们希望数据库强制执行约束,以便永远不会插入错误的数据。
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'(CHECK约束,触发或引用单行查找表),那么它当然可以引用A中的父行,其中type ='B'。并在表C和D中执行类似的操作,因此A的每一行只能由一个子类型表中的行引用。
也就是说,如果给定行上的A.type是'B',而C.type只能是'C',那么没有C行可以引用A.type为'B'的任何行。
现在,如果您希望表Z引用B或C而不是D,则可以通过id 和类型引用,因此Z也有自己的类型列。您可以使用查找表限制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)
);
答案 1 :(得分:0)
你已经得到了你想要的答案。但对于遇到这种情况的其他人来说,值得研究两种技术:类表继承和共享主键。
这两种技术结合使用,可以快速,简单,轻松地将A的数据与B或C的数据连接起来。在这种模式中,B只包含密钥,但仍包含有用的信息。
这两种技术都有自己的标签。