Postgres upsert避免第二唯一约束吗?

时间:2019-11-05 20:20:52

标签: postgresql unique-constraint upsert

我有一个表格的形式(基于):

create table foo (
  name text unique,
  ref_id int,
  mod_time timestamptz
);

我希望能够插入其中,但是 如果正在使用mod_timename对,则更新ref_id,如果另一个name使用ref_id则失败。

我可以通过创建另一个唯一约束来做到这一点,如下所示:

alter table foo add unique (name, ref_id);

然后

insert into foo values ( $1, $2, $3 )
on conflict (name, ref_id) do update set
  mod_time = excluded.mod_time;

将按我的意愿运行:

  • 如果使用新名称,则插入
  • 如果名称和ref_id相同,则更改mod_time
  • 如果不同ref_id的名称相同,则会失败

但是,成本是第二唯一索引,实际上对于执行约束来说是多余的,因为name唯一的记录将自动被nameref_id唯一。 是否有一些解决方法可以让我在没有第二个索引的情况下,也无需与数据库进行额外往返,就可以得到这种行为?

1 个答案:

答案 0 :(得分:1)

这取决于您所说的失败。如果在这种情况下不做任何事情是可以的:where If same name for different ref_id,则可以执行以下操作:

insert into foo values ($1, $2, $3)
on conflict (name) DO update set
mod_time = excluded.mod_time
WHERE foo.ref_id = excluded.ref_id;

您可以在运行查询后检查修改了多少行,如果没有修改则引发异常。

相关问题