Suppose I have table like:
CREATE TABLE foo (
id SERIAL PRIMARY KEY
, barid integer NOT NULL REFERENCES bar(id)
, bazid integer NOT NULL REFERENCES baz(id)
, startdate timestamp(0) NOT NULL
, enddate timestamp(0) NOT NULL
);
The purpose for that table is to provide a pseudo 'one-to-many' relation between tables bar and baz, but the relation can change through time:
SELECT * FROM bar
JOIN foo on TRUE
AND foo.barid = bar.id
AND now() BETWEEN foo.startdate AND foo.enddate
JOIN baz on baz.id = foo.bazid
We can imagine, that for a certain row from bar
table we want to find a corresponding row in baz
table, but the corresponding row may be different in different time periods - so it should return different row for now, different for last month etc.
Now my question is: what would be the best way to validate data integrity in this table? To be specific, I need to be sure, that for a certain timestamp, there will be only one row in table foo
for foo.barid
. I know I can write a trigger (which seems the only option for my by now), but maybe someone has a simpler idea? I was thinking of using some kind of partial index, but I'm not sure how to write a condition ...
And by "timestamp" you seem to mean a certain period of time.
An exclusion constraint on a range type, combined with equality on
barid
(utilizing the additional modulebtree_gist
) would be the perfect solution.This requires Postgres 9.2 or later.
Related:
The manual has a matching code example!