Re: how do I update or insert efficently in postgres

From: Tom Lane <tgl(at)sss(dot)pgh(dot)pa(dot)us>
To: marc(at)oscar(dot)eng(dot)cv(dot)net (Marc Spitzer)
Cc: pgsql-sql(at)postgresql(dot)org
Subject: Re: how do I update or insert efficently in postgres
Date: 2001-11-13 21:04:44
Message-ID: 3557.1005685484@sss.pgh.pa.us
Views: Raw Message | Whole Thread | Download mbox | Resend email
Thread:
Lists: pgsql-sql

marc(at)oscar(dot)eng(dot)cv(dot)net (Marc Spitzer) writes:
> I need to do the follwoing logic for a db I am building:
> if row exists update some fields
> else insert all fields

> I have come across this befor and have used select to drive the
> choice, if I could get the row update else insert.

Which case do you think will be more common? If UPDATE is the more
common scenario then it's a win to do

UPDATE set modifiable-fields = whatever WHERE key = whatever
if (zero rows updated)
INSERT ...

Alternatively you can do

INSERT ...
if (fail due to duplicate key)
UPDATE ...

if you think INSERT is the more common case. (This all assumes you
have a unique key for the table, but if you don't, then what do you
mean by "the row already exists"?)

Neither of these are perfect, however. The former has a race condition
if two clients might try to insert the same key at about the same time.
You can improve it to

BEGIN;
UPDATE set modifiable-fields = whatever WHERE key = whatever
if (zero rows updated)
{
INSERT ...
if (fail due to duplicate key)
{
ABORT;
loop back to BEGIN;
}
}
COMMIT;

but this is kinda ugly. (Of course, if you could have two clients
independently inserting/updating the same row at the same time, you
have problems anyway: which one should win, and why? I think the
coding difficulty may tell you you have a design problem.)

As for the INSERT-then-UPDATE approach, you have the same problem
that you have to ABORT and start a new transaction if the INSERT
fails. This is uncool if you really want the whole thing to be part
of a larger transaction.

But as long as you've guessed right about which case is more common,
you have only one query most of the time.

regards, tom lane

In response to

Responses

Browse pgsql-sql by date

  From Date Subject
Next Message Wilco Boschman 2001-11-13 21:33:03 Re: Insert values from one existing table into a new table.
Previous Message Jocelyn Callier 2001-11-13 20:26:48 Full text search