PostgreSQL 中继承表的外键

huangapple go评论69阅读模式
英文:

Foreign key for inherited table in PostgreSQL

问题

我有从targets表继承的animalswater表。它们看起来像这样:

targets

create table targets
(
    id   integer not null
        primary key,
    name text
);

animals(water表相同)

create table animals
(
    type_id  integer,
    flock_id integer,
    primary key (id)
)
    inherits (targets);

我还有一个actions表,它有一个外键target_id

actions

create table actions
(
    id        integer not null
        primary key,
    target_id integer
        references targets(id),
);

我在animalswater表中有一些行。我尝试向actions表中插入新行,其中target_id等于某个动物的id。

INSERT INTO actions (id, target_id)
VALUES (1, 4);

但我收到一个错误:

[23503] ERROR: insert or update on table "actions" violates foreign key constraint "actions_target_id_fkey"
Key (target_id)=(4) is not present in table "targets".

也许我不理解表的继承,但我如何才能正确执行我的任务(target_id应同时成为wateranimals表的外键)?

英文:

I have tables animals and water inherited from targets table. They look like this:

targets

create table targets
(
    id   integer not null
        primary key,
    name text
);

animals (water table is the same)

create table animals
(
    type_id  integer,
    flock_id integer,
    primary key (id)
)
    inherits (targets);

Also I have a actions table which has a foreign key target_id.

actions

create table actions
(
    id        integer not null
        primary key,
    target_id integer
        references targets(id),
);

I have some rows in animals and water tables. And I am trying to insert new row into actions table with target_id equals to id of some animal.

INSERT INTO actions (id, target_id)
VALUES (1, 4);

But I receive an error:

> [23503] ERROR: insert or update on table "actions" violates foreign key constraint "actions_target_id_fkey"
Key (target_id)=(4) is not present in table "targets".

Maybe I don't understand the table's inheritance, but how can I do my task correctly (target_id should be a foreign key for water and animals tables at the same time)?

答案1

得分: -1

CREATE TABLE some_table (
id serial primary key,
target_id integer references targets(id),
-- other columns
CONSTRAINT target_id_animals_water_check CHECK (
target_id IN (SELECT id FROM animals)
OR target_id IN (SELECT id FROM water)
)
);

some_table 是你想要创建外键的表名,target_id 是将存储外键的列名。references 子句指定 target_id 列应引用 targets 表的 id 列。

CHECK 约束确保引用的行在动物或水表中。使用 IN 运算符来检查 target_id 是否在动物或水表的 id 值集合中。

有了这个设置,你可以向动物和水表以及some_table表中插入行,外键约束将确保只允许有效的引用,并且你可以像这样向some_table表中插入一行:

INSERT INTO some_table (target_id) VALUES (1);

英文:

I hope this might wrork , you have two tables, animals and water, that inherit from a parent table, targets. You want to create a foreign key in a different table that can reference both the animals and water tables using the id columnn of the targets table.

for that, you can create a foreign key that references the id column of the targets table and use a CHECK constraint to ensure that the referenced row is in either the animals or water table

CREATE TABLE some_table (
id serial primary key,
target_id integer references targets(id),
-- other columns
CONSTRAINT target_id_animals_water_check CHECK (
    target_id IN (SELECT id FROM animals)
    OR target_id IN (SELECT id FROM water)
)

);

some_table is the name of the table that you want to create the foreign key in, and target_id is the name of the column that will store the foreign key. The references clause specifies that the target_id column should reference the id column of the targets table.

The CHECK constraint ensures that the referenced row is in either the animals or water table. The IN operator is used to check if the target_id is in the set of id values in either the animals or water table.

With this setup, you can insert rows into the animals and water tables as well as the some_table table, and the foreign key constraint will ensure that only valid references are allowed and you can insert a row into the some_table table like this
INSERT INTO some_table (target_id) VALUES (1);

huangapple
  • 本文由 发表于 2023年2月18日 17:02:58
  • 转载请务必保留本文链接:https://go.coder-hub.com/75492260.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定