如何将外键约束到子集

doe*_*man 4 postgresql

我有一张桌子employee,他们每个人都可以扮演不同的角色,比如inspector constructor 。我还有另一张桌子,上面有一列,我可以在其中存储检查员在工作中的内容。

人们可以扮演不同的角色,但角色不一定要动态添加;为员工的每个角色设置一列就足够了。这也很方便,因为我们目前资源有限,而我们的用户使用 Postico 来维护数据(目前),因此最好使用简单的数据模型。有了外键,我们可以使用 Postico 的 1:N 选择器。

我试图为(物化)视图创建外键约束,但这不受 Postgresql 支持。此外,不允许使用以下外键:

FOREIGN KEY("inspector_id", TRUE) REFERENCES employee("id", "is_inspector")
Run Code Online (Sandbox Code Playgroud)

除了在多个表中复制数据之外,我还有其他选择吗?

ype*_*eᵀᴹ 5

首先,您不必复制数据。

如果添加inspector表,则不会重复。您的模型中需要一个“检查员”实体,您添加一个“检查员”表。只有inspector_id值会被复制,这很好。所以,这是解决方案A。

解决方案 B 可能是is_inspector在要具有外键的表中添加一列并将该列限制为TRUE

is_inspector BOOLEAN DEFAULT TRUE,
CHECK (is_inspector),
FOREIGN KEY (inspector_id, is_inspector) 
  REFERENCES employee(id, is_inspector)
Run Code Online (Sandbox Code Playgroud)

我每次都会选择解决方案 A,但如果解决方案 B 出于某种原因简化了您的应用程序代码,它仍然可以解决问题并强制执行相同的要求。但是,如果您以后需要其他表来引用“检查员”,那么您还需要在每个表中都有一个布尔列。因此,解决方案 A 是更简单的方法,因为它根本不需要任何此类布尔列(即使在employee表中,您也可以通过加入inspector表来找到检查员)。

  • 我将 `DEFAULT` 设置为 false - 当然只有少数员工是检查员。我对这个问题(和答案)给予 +1,因为它提出了一个有趣的观点:为什么不能有“PARTIAL FOREIGN KEY”? (2认同)