PostgreSQL
 sql >> Datenbank >  >> RDS >> PostgreSQL

Teilweise eindeutiger PostgreSQL-Index und Upsert

Ich glaube nicht, dass es möglich ist, mehrere Teilindizes als Konfliktziel zu verwenden. Sie sollten versuchen, das gewünschte Verhalten mit einem einzigen Index zu erreichen. Die einzige Möglichkeit, die ich sehen kann, besteht darin, einen eindeutigen Index für Ausdrücke zu verwenden:

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, ''));

Jetzt verletzen alle drei Tests (zweimal ausgeführt) denselben Index:

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

Im Einfügebefehl sollten Sie die in der Indexdefinition verwendeten Ausdrücke übergeben:

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;