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_id
或 league_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;
在 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_id
或 league_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;