Postgres继承和外键或替代键

时间:2019-10-24 12:41:35

标签: postgresql inheritance foreign-keys

我在项目中使用了postgres继承。

例如:我有一个“用户”表和一个从“用户”表继承的“ user_child”。

我有两条记录:第一条记录在user表中创建,第二条记录在user_child表中创建,而user_child的记录由于继承而部分存储在用户中。

我还有第三个表-“ homework”,它具有一列named_user-用户表的外键。

当我将记录添加到“任务”表中时,其中“ assigned_user”字段引用了user表中的一条记录,那么一切都很好,但是当我从{{1}中选择一条记录时}表,出现错误:

  

错误:在表“作业”上插入或更新违反外键   约束“ fk-homework-assigned_user””

     

详细信息:表“用户”中没有键(assigned_user)=(3)。

删除约束有助于解决我的问题,但是我想使用级联删除和更新记录。你能告诉我那里有什么替代方案还是我做错了什么?

1 个答案:

答案 0 :(得分:0)

PostgreSQL继承与您期望的不太一样。是的,查询父表时可以从子表中看到信息,但这并不扩展到外键关系。该行“属于”孩子,而不是父母。外键引用不会碰到孩子。

在PostgreSQL中使用继承通常不是一个好主意,除了特殊的情况(例如建立临时系统或强制命名约定(例如OOP中的接口而不是状态继承))之外。

PostgreSQL继承可以非常强大,但是我认为它通常被滥用。已经有一种解决方案(与跨数据库兼容)可以更紧密地遵循传统的关系模型。

一个更好的模型可以满足您的需求:

CREATE TABLE "user" (
  user_id serial PRIMARY KEY, -- Or UUID or generated column in newer versions
  -- other fields that all "children" should share
);

CREATE TABLE user_child (
  user_id integer NOT NULL
    REFERENCES "user" (user_id) ON UPDATE CASCADE ON DELETE CASCADE,
  -- other fields specific to the child
);

CREATE TABLE homework (
  homework_id serial PRIMARY KEY,
  user_id integer NOT NULL
    REFERENCES "user" (user_id) ON UPDATE CASCADE ON DELETE RESTRICT,
  -- other fields specific to homework
);

与查询user_child等效的是

SELECT u.user_id
FROM "user" AS u
  INNER JOIN user_child AS uc;

要查询用户,父级和子级仍然是

SELECT u.user_id
FROM "user" AS u;

添加内部联接非常简单,并且可以隐藏在视图后面。现在,您对“用户”的外键引用将正常运行。

相关问题