PostgreSQL:如何限制外键上的存在?

时间:2010-10-19 19:29:30

标签: sql postgresql foreign-keys constraints

在PostgreSQL中,在外键上强制执行的不仅仅是最简单的方法是什么?

例如,给出以下表格:

create table "bar"
    (
    bar_id serial primary key,
    status boolean not null
    )

create table "foo"
    (
    foo_id serial primary key,
    bar_id integer references "bar"
    )

foo.bar_id如何仅限bar status的行{?}}?

我可以想象如何使用触发器功能,但似乎我需要多个insertupdate foo; update,{{ 1}} delete}所以我想知道是否有更方便的方法,也许纯粹是使用约束。

4 个答案:

答案 0 :(得分:1)

硬核方法是在foo和bar之间放置一个中间/子类别表,其中包含状态为true的条形值。 foo上的外键将指向中间表,但如果添加了条形值或状态更改为false,则需要在两侧进行维护...

另一种方法是使用触发器,因为外键无法过滤。

PostgreSQL没有物化视图;我不确定它是否允许您指定视图的外键引用,但如果条形状态更改为false,则表示存在问题...

答案 1 :(得分:1)

这是标准SQL关系完整性无法满足实际需求的众多情况之一。例如,我希望可以创建一个针对索引而不是整个列的外键; postgresql提供部分索引,这将解决您的问题。

如果失败了,你需要将bar分为两个表bar_true和bar_false,每个没有状态字段。根据bar_true建立你的FK。然后,您可以一起创建一个UNIONing bar_true和bar_false视图以获得完整的条形图集(尽管您必须小心使用主键)。

答案 2 :(得分:1)

您可以将bar.status作为条形图主键的一部分。然后将状态放在foo表上作为FK的一部分来禁止。还要设置foo.status必须等于true的约束。这是一种黑客攻击,但根据现实世界的情况,它可能有意义。

答案 3 :(得分:0)

似乎你是否使用了触发器,你可以控制只让记录进入foo,条形状态为true,你也可以在bar上设置一个触发器,如果​​状态变为false,它将删除foo中的记录。