Database Design Advice
Smylers
Smylers at stripey.com
Mon Nov 18 09:25:43 GMT 2013
Dagfinn Ilmari Mannsåker writes:
> Smylers <Smylers at stripey.com> writes:
>
> > Here it is in Postgres's own function language, which goes by the
> > awkwardly written name PL/pgSQL:
> >
> > CREATE OR REPLACE FUNCTION set_document_version_num() RETURNS TRIGGER AS
> > $FN$
> > BEGIN
> > NEW.version := 1 +
> > MAX(version)
> > FROM document_version
> > WHERE document_id = NEW.document_id;
> > RETURN NEW;
> > END;
> > $FN$ LANGUAGE plpgsql;
> >
> > CREATE TRIGGER insert_document_version_num
> > BEFORE INSERT ON document_version FOR EACH ROW
> > EXECUTE PROCEDURE set_document_version_num();
>
> This trigger works fine, until you get concurrent saves of the same
> document, in which case one of the transactions will get a duplicate key
> violation.
Ah, thank you for pointing that out.
In this case I think having a collision, and hence an error, may
actually be desirable: the application can detect the error and warn the
user that another change has already been made.
> If you want both to succed, with the last one winning, you can do it
> by keeping the current version in the document table,
I had been thinking that doing that would be bad, because it's
redundant, even though having it looks like it'd be convenient in a few
places.
> and making the trigger update it:
But that sounds quite nice, the duplication seems liveable-with when
it's managed with a trigger.
> ALTER TABLE document
> ADD COLUMN current_version INTEGER NOT NULL DEFAULT 0;
>
> REPLACE FUNCTION set_document_version_num() RETURNS TRIGGER AS
> $FN$
> BEGIN
> UPDATE document
> SET current_version = current_version + 1
> WHERE id = NEW.document_id
> RETURNING current_version
> INTO NEW.version;
> RETURN NEW;
> END
> $FN$ LANGUAGE plpgsql;
I do like Postgres's RETURNING clauses — they seem so much more flexible
and elegant than other ways of achieving the same ends.
Cheers
Smylers
--
The UK gov's proposed gagging law will suppress protest and campaigning by
charities and political groups. Read more: http://civilsocietycommission.info/
Please sign this petition: http://38d.gs/1cJ9ViA
Oxfam • BHA • Quakers * Countryside Alliance • League Against Cruel Sports • CND
More information about the london.pm
mailing list