【问题标题】:Foreign keys + table inheritance in PostgreSQL?PostgreSQL中的外键+表继承?
【发布时间】:2014-08-13 03:53:19
【问题描述】:

我有三个表:organizationorganization_teamsorg_users。这里organization_teams 继承自organization。所以假设如果在organizations_teams 中添加一条记录,它将获得organizationid 作为organization_teamsid 列的值。

org_usersorganizationid 列上有外键。现在,当我尝试在 org_users 中插入数据时,它给了我如下错误

insert or update on table "org_users" violates foreign key constraint "org_users_organizations"
DETAIL:  Key (org_id)=(12) is not present in table "organizations"

为什么?

【问题讨论】:

  • 没有。序列不是继承的。
  • 这是已知的警告:继承功能的一个严重限制是索引(包括唯一约束)和外键约束仅适用于单个表,而不适用于它们的继承子表 postgresql.org/docs/current/static/…
  • 我已经有一些组织在组织表和组织_团队中,所以 org_user 在组织上有外键。

标签: postgresql inheritance


【解决方案1】:

我是covered in the user manual

简短版:您可以使用外键或表继承,但不能同时使用。这并非天生不可能,只是在技术上很难以快速、可靠的方式实现跨越 PostgreSQL 中继承表的唯一索引。没有它,您将无法拥有有用的外键。还没有人成功地实现它,以至于一个补丁添加支持被 PostgreSQL 接受。

外键可以指向作为继承层次结构一部分的表,但它只能准确地在该表中找到行。不在任何父表或子表中。要查看外键看到的行,请执行SELECT * FROM ONLY thetableONLY 关键字的意思是“忽略继承”,这就是外键查找的作用。

【讨论】:

  • 仅在表继承层次结构的“叶”表中应用外键是否“安全”?
  • @AndrewWolfe 如果引用表和被引用表在同一个键上分区,则可以在相应分区之间使用 FK。就是这样。
【解决方案2】:

我发现的唯一解决方法是:

  1. 创建函数返回触发器以检查某些 id 的存在 在继承表中
  2. 创建约束触发器而不是 FK

【讨论】:

    【解决方案3】:

    完全同意@Craig Ringer,我们不能在继承的同时使用外键。

    但是如果我们确定要插入正确的数据,并且我们想在 org_users 中使用外键,我们可以做一件事。

    我们可以创建一个 org_users 的子表,比如 org_users_child(没有外键),如下所示

    CREATE TABLE org_users_child () INHERITS (org_users);
    

    现在我们可以在这个子表中插入数据了。

    现在如果我们查询 org_users 表,我们可以找到想要的结果。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2011-06-23
      • 1970-01-01
      • 2012-06-09
      • 2022-01-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多