2

我有一个关于我遇到的设计问题的疑问......</p>

有一个表 A 具有子类型 B 和 C。表 A 有一个属性类型,它告诉类型是 B 还是 C。 B 和 C 的公共属性在 A 中。

问题是 B 没有额外的属性 .. B 所需的所有属性都已经在 A 中。但是,C 有额外的属性。

如果我只制作表 A 和 C,这是一个可接受的解决方案吗??...提取 BI 的实体将通过表 A 中的类型属性进行查询

你可以参考任何材料吗?

我还有另一个困惑,表 A 有子类型 B,C,D 。表 Z 有一列需要主 ID 值为 B 或 C 但不是 D。

我想将 A 的主 id 列添加为对 Z 列的外键引用,然后进行触发器以确保 id 不是 D ...

任何人都可以评论吗?

谢谢 !

4

2 回答 2

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”(检查约束、触发器或引用单行查找表),那么它当然可以引用 A 中 type='B' 的父行。并在表 C 和 D 中执行类似的操作,因此 A 的每一行只能被一个子类型表中的一行引用。

也就是说,如果 A.type 在给定行上是“B”,而 C.type 只能是“C”,则 C 的任何行都不能引用 A.type 为“B”的任何行。

现在如果你想让表 Z 引用 B 或 C 而不是 D,你可以通过 idtype 来引用,所以 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)
);
于 2012-11-30T19:27:28.753 回答
0

你已经得到了你正在寻找的答案。但是对于遇到此问题的其他人来说,值得研究两种技术:类表继承和共享主键。

这两种技术一起使用使得将 A 的数据与 B 或 C 的数据连接起来变得快速、简单和容易。在这个模式中,B 只包含密钥,但仍然包含有用的信息。

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

于 2012-12-01T02:05:29.850 回答