PostgreSQL 独占或列设置

PostgreSQL exclusive or on column setting

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

的东西
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
)

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

可以吗?

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

alter table foo add 
   constraint check_team check (not (team_id is not null and league_id is not 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;