Postgres继承和外键或替代



我在项目中使用postgres继承。

例如:我有一个"user"表和从"user"表格继承的"user_child"。

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

我还有第三个表——"作业",它有一个列assigned_user——用户表的外键。

当我将一条记录添加到"任务"表中时,其中"assigned_user"字段指的是user表中的一条记录,那么一切都很好,但当我从user_child表中选择一条记录时,我会得到一个错误:

错误:插入或更新表"作业"违反外键约束"fk-homework-assigned_user">

详细信息:表"user"中不存在键(assigned_user(=(3(。

删除约束有助于解决我的问题,但我希望使用级联删除和更新记录。你能告诉我还有什么选择吗?或者我做错了什么?

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;

添加内部联接是非常琐碎的,并且可能隐藏在视图后面。现在,您对"user"的外键引用将正常工作。

最新更新