Unix Technical Forum

Index to enforce non-overlapping ranges?

This is a discussion on Index to enforce non-overlapping ranges? within the pgsql Sql forums, part of the PostgreSQL category; --> Academic question here: Given a table with a pair of any sort of line-segment-esqe range delimiter columns, is it ...


Go Back   Unix Technical Forum > Database Server Software > PostgreSQL > pgsql Sql

Register FAQ Members List Calendar Search Today's Posts Mark Forums Read
  #1 (permalink)  
Old 05-10-2008, 02:06 PM
James Robinson
 
Posts: n/a
Default Index to enforce non-overlapping ranges?

Academic question here:

Given a table with a pair of any sort of line-segment-esqe range
delimiter columns, is it possible to build a unique index to enforce
non-overlapping ranges? Such as:

create table test
(
id int not null primary key,
low_value int not null,
high_value int not null
);

Can one build an index to enforce a rule such that no (low_value,
high_value) range is identical or overlaps with another (low_value,
high_value) range described by the table? And, more interestingly,
what about for ranges of dates / timestamps as opposed to simple
integers?

I can see how a trigger on insert or update could enforce such a
constraint [ probe the table for an existing overlapping row, and
raise exception one exists ], but can such an activity be performed
with fewer lines using some sort of r-tree index?

----
James Robinson
Socialserve.com


--
Sent via pgsql-sql mailing list (pgsql-sql@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-sql

Digg this Post!Add Post to del.icio.usBookmark Post in TechnoratiFurl this Post!
Reply With Quote
  #2 (permalink)  
Old 05-10-2008, 02:06 PM
Tom Lane
 
Posts: n/a
Default Re: Index to enforce non-overlapping ranges?

James Robinson <jlrobins@socialserve.com> writes:
> Given a table with a pair of any sort of line-segment-esqe range
> delimiter columns, is it possible to build a unique index to enforce
> non-overlapping ranges?


Nope, sorry. Unique indexes enforce non-equality, but there's no way
to pretend that "overlaps" is an equality condition (hint: it's not
transitive).

I don't say that it'd be impossible to construct an index type that
could do this, but you won't get there with the pieces we have.

regards, tom lane

--
Sent via pgsql-sql mailing list (pgsql-sql@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-sql

Digg this Post!Add Post to del.icio.usBookmark Post in TechnoratiFurl this Post!
Reply With Quote
  #3 (permalink)  
Old 05-10-2008, 02:06 PM
Chris Browne
 
Posts: n/a
Default Re: Index to enforce non-overlapping ranges?

jlrobins@socialserve.com (James Robinson) writes:
> Academic question here:
>
> Given a table with a pair of any sort of line-segment-esqe
> range delimiter columns, is it possible to build a unique index to
> enforce non-overlapping ranges? Such as:
>
> create table test
> (
> id int not null primary key,
> low_value int not null,
> high_value int not null
> );
>
> Can one build an index to enforce a rule such that no
> (low_value, high_value) range is identical or overlaps with another
> (low_value, high_value) range described by the table? And, more
> interestingly, what about for ranges of dates / timestamps as opposed
> to simple integers?
>
> I can see how a trigger on insert or update could enforce such
> a constraint [ probe the table for an existing overlapping row, and
> raise exception one exists ], but can such an activity be performed
> with fewer lines using some sort of r-tree index?


Aside: A constraint won't do what you want, because a CHECK constraint
can only reference the columns of the current row.

This is a useful sort of thing to have in a temporal database, where
you might want to add temporal constraints to what was originally a
stateful table which had an ordinary primary key.

Thus, we might start with table:

create table state_of_something (
id serial primary key,
att1 text,
att2 text,
att3 text
);

and want to make it temporal. The temporal equivalent (well, *one*
temporal equivalent; there's several ways to treat this) would be:

create table temporal_state_of_something (
id serial,
att1 text,
att2 text,
att3 text,
from_date timestamptz,
to_date timestamptz
);

where the requirement, for any given id value, is for there to be a
series of non-overlapping (from_date,to_date) intervals.

A *vague* approximation that is easy to do is to have a new primary
key:

create table temporal_state_of_something (
id serial,
att1 text,
att2 text,
att3 text,
from_date timestamptz,
to_date timestamptz,
primary key (id, from_date),
constraint from_to check (to_date >= from_date)
);

That doesn't prevent there from being overlapping ranges, such as
(id,from_date_to_date) tuples like:

(151,'2007-01-01','2009-01-01') and (151 '2008-01-01','2008-02-02')

I'm not sure that this is *so* different from a regular foreign key
constraint that it wouldn't be reasonable to handle it via a trigger.
It's certainly a more complex trigger function, but the pattern will
be pretty common.
--
output = ("cbbrowne" "@" "linuxfinances.info")
http://linuxdatabases.info/info/linuxdistributions.html
Those who do not learn from history, loop.
Digg this Post!Add Post to del.icio.usBookmark Post in TechnoratiFurl this Post!
Reply With Quote
Reply


Thread Tools
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

vB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are On
Forum Jump


All times are GMT. The time now is 03:34 AM.


Powered by vBulletin® Version 3.6.5
Copyright ©2000 - 2008, Jelsoft Enterprises Ltd.
SEO by vBSEO 3.2.0
www.UnixAdminTalk.com