PostgreSQL独占或列设置

时间:2016-07-22 05:44:14

标签: postgresql postgresql-9.5

在PostgreSQL 9.5中我想创建一个包含三列的表。我基本上有类似

的东西
create table Foo (
   account varchar not null,
   team_id integer references team (ident) on delete cascade,
   league_id integer references league (ident) on delete cascade
)

现在有趣的部分是我希望他们指定EITHER team_idleague_id,但不能同时指定两者。 account加上其他两列中的一列的组合就是UNIQUE约束。

这可能吗?

1 个答案:

答案 0 :(得分:2)

要确保只提供其中一列,请使用检查约束:

alter table foo add 
   constraint check_team check (not (team_id is not null and league_id is not null));

但是,上述内容不会阻止为两个列提供NULL值。如果您想确保提供完全其中一个,您可以使用:

alter table foo add 
   constraint check_team check ( (team_id is not null or league_id is not null) 
                                 and not (team_id is not null and league_id is not null));

编辑:正如Abelisto指出的那样,检查约束可以简化为

alter table foo add 
   constraint check_team check ((team_id is null) <> (league_id is null));

我不确定您想要建立的唯一约束。如果是应该阻止以下两行('x', 1, null)('x', null, 1)然后您可以使用这样的唯一索引:

create unique index on foo (account, coalesce(team_id, league_id));

只有在您强制执行至少其中一列不必为空的规则时,这才能正常工作。

但是,如果你想在不同的列中允许同一个团队,但是想要防止为一个帐户设置两次相同的team_id或league_id(允许上面的例子),那么我认为你需要唯一的索引:

create unique index on foo (account, team_id) where team_id is not null; 
create unique index on foo (account, league_id) where league_id is not null;