4

我想在插入新行时将主键列的值从父表传播到特定的子表。

出于解释目的,我创建了以下表格:

Create TABLE Material(
MatID serial PRIMARY KEY,
materialname TEXT
);

Create TABLE RealMaterial(
MatID INT REFERENCES Material(MatID),
attributereal TEXT,
PRIMARY KEY(MatID)
);

Create TABLE VirtualMaterial(
MatID INT REFERENCES Material(MatID),
attributevirt TEXT,
PRIMARY KEY(MatID)
);

当我插入新材料时,我会自动添加 aRealMaterial或 a VirtualMaterial(引用新 ID)。我应该强调我想使用这种共享主键模式,而不仅仅是单表继承。

我应该为我的目的使用触发器吗?

4

2 回答 2

2

从您的评论看来,您实际上并不关心“自动插入”,而是“自动执行”儿童的存在1排他性2

由于 PostgreSQL 支持延迟约束,您可以像这样声明性地执行它。

但是,它需要“丑化”您的模型并且通常会增加复杂性,因此在应用程序级别执行此类约束通常被认为是一种较小的邪恶。您可以考虑将这种逻辑隐藏在 API 后面,以消除“流氓”客户端绕过它的可能性。


1对于给定的父行,必须有一个子行。换句话说,父类不能单独实例化——它是抽象的。

2对于给定的父行,子行不能超过一个。

于 2014-04-29T20:13:39.267 回答
0

我真的不明白你所有的领域是什么意思,你也没有真正提供很多信息,但你可以通过触发器来完成这一点。同样,这里的信息不多,所以我不打算写一个有效的例子,但一个伪代码片段是:

IF (TG_OP = 'INSERT') THEN
    IF NEW.Parameter = 'REAL' THEN
        INSERT INTO RealMaterial (MatID) VALUES (NEW.MatID);
    ELSE
        INSERT INTO VirtualMaterial (MatID) VALUES (NEW.MatID);
    END IF;
END IF;

我不知道 Material.Parameter 与 Parameter2 和 Parameter3 之间的关系(如果有的话)。假设 Material.Parameter 控制材质是真实的还是虚拟的,那么您将需要处理 INSERTS 和 UPDATES 并能够将材质从“RealMaterial”移动到“VirtualMaterial”,反之亦然。您可能可以使用外键(级联)处理删除。

两条不请自来的建议:

  1. 发布时,请始终提供尽可能多的(相关)信息。这将导致更好的答案。在这里解释关系会有所帮助。此外,您应该始终包含有关您正在使用的 PostgreSQL 版本的信息。
  2. 根据我的经验,感觉就像您不需要不同的桌子,而是一张桌子。我强烈考虑将其实现为单个表。
于 2014-04-29T15:53:29.163 回答