有关继承和外键引用的数据库设计查询

时间:2012-11-30 19:06:37

标签: sql database-design inheritance foreign-keys

我对我遇到的设计问题有疑问......

表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 ...

任何人都可以发表评论吗?

谢谢!

2 个答案:

答案 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只包含密钥,但仍包含有用的信息。

这两种技术都有自己的标签。