当前位置: 首页 > 知识库问答 >
问题:

PostgreSQL部分唯一索引与upsert

充运浩
2023-03-14
create table test (
    p text not null,
    q text,
    r text,
    txt text,
    unique(p,q,r)
);

create unique index test_p_idx on test(p) where q is null and r is null;
create unique index test_pq_idx on test(p, q) where r IS NULL;
create unique index test_pr_idx on test(p, r) where q is NULL;
insert into test(p,q,r,txt) values ('p',null,null,'a'); -- violates test_p_idx
insert into test(p,q,r,txt) values ('p','q',null,'b'); -- violates test_pq_idx
insert into test(p,q,r,txt) values ('p',null, 'r','c'); -- violates test_pr_idx
insert into test as u (p,q,r,txt) values ('p',null,'r','d') 
on conflict (p, q, r) do update 
set txt = excluded.txt

我做错了什么?我应该使用index_predicate吗?

用于允许推断部分唯一索引的index_predicate。可以推断出满足谓词的任何索引(实际上不必是部分索引)。遵循创建索引格式。https://www.PostgreSQL.org/docs/9.5/static/sql-insert.html

共有1个答案

翁烨霖
2023-03-14

我不认为使用多个部分索引作为冲突目标是可能的。您应该尝试使用单个索引来实现所需的行为。我能看到的唯一方法是对表达式使用唯一索引:

drop table if exists test;
create table test (
    p text not null,
    q text,
    r text,
    txt text
);

create unique index test_unique_idx on test (p, coalesce(q, ''), coalesce(r, ''));

现在所有三个测试(执行两次)都违反了相同的索引:

insert into test(p,q,r,txt) values ('p',null,null,'a'); -- violates test_unique_idx
insert into test(p,q,r,txt) values ('p','q',null,'b');  -- violates test_unique_idx
insert into test(p,q,r,txt) values ('p',null, 'r','c'); -- violates test_unique_idx

在insert命令中,您应该传递索引定义中使用的表达式:

insert into test as u (p,q,r,txt) 
values ('p',null,'r','d') 
on conflict (p, coalesce(q, ''), coalesce(r, '')) do update 
set txt = excluded.txt;
 类似资料:
  • 以下两者之间有区别吗: 以及: 在这两种情况下,名称是否唯一?索引唯一时意味着什么? 编辑:Postgres是唯一的约束,而索引没有回答我的问题。它考虑了FK的情况。我的问题与FK无关。我只想知道在这个例子中,这两个操作是否等价,其中不涉及FK。

  • 问题内容: 就性能而言,MySQL唯一索引和非唯一索引有什么区别? 假设我要在2列的组合上创建索引,并且该组合是唯一的,但是我创建了一个非唯一的索引。这会对MySQL使用的性能或内存产生重大影响吗? 同样的问题, 主 键和 唯一 索引之间有区别吗? 问题答案: UNIQUE和PRIMARY KEY是 约束 ,而不是索引。尽管大多数数据库通过使用索引来实现这些约束。除了索引之外,约束的额外开销也微不

  • 问题内容: SQLAlchemy支持在postgresql中创建部分索引。 是否可以通过SQLAlchemy创建部分 唯一 索引 ? 像这样想象一个表/模型: 我想要一个唯一的索引,对于给定的发票,该索引只能有一个“活动”的ScheduledPayment。 我可以在postgres中手动创建它: 我想知道如何使用SQLAlchemy 0.9将其添加到我的SQLAlchemy模型中。 问题答案:

  • CreateIndexes 根据struct中的tag来创建索引 CreateUniques 根据struct中的tag来创建唯一索引

  • PostgreSQL 官方文档关于部分索引给了以下一个示例: Example 11.2. Setting up a Partial Index to Exclude Uninteresting Values If you have a table that contains both billed and unbilled orders, where the unbilled orders tak

  • 问题内容: 我有一个按TRANSACTION_DATE_TIME分区的表。 表中有一列:ID。 我想为分区方案上的ID创建唯一索引: 但是SQL表示“唯一索引的分区列必须是索引键的子集”。 我真的不需要此索引中的TRANSACTION_DATE_TIME列。 如何在不使用TRANSACTION_DATE_TIME列的情况下创建索引? 问题答案: 或者你创建 非 -partitioned索引,或者您