Comments on: Temporal Keys, Part 2 http://thoughts.davisjeff.com/2009/11/08/temporal-keys-part-2/ Ideas on Databases, Logic, and Language by Jeff Davis Tue, 19 Jun 2012 16:18:51 +0000 hourly 1 http://wordpress.org/?v=3.3.1 By: Jeff Davis http://thoughts.davisjeff.com/2009/11/08/temporal-keys-part-2/comment-page-1/#comment-240 Jeff Davis Sat, 31 Jul 2010 20:48:55 +0000 http://thoughts.davisjeff.com/?p=180#comment-240 The type input function reads the inclusivity/exclusivity as you would expect. [2009-01-01-2009-02-01) does not include the final endpoint, but does include the starting point. (2009-01-01, 2009-02-01] does not include the start point but does include the end point. () and [] are also allowed. The type input function reads the inclusivity/exclusivity as you would expect. [2009-01-01-2009-02-01) does not include the final endpoint, but does include the starting point. (2009-01-01, 2009-02-01] does not include the start point but does include the end point. () and [] are also allowed.

]]>
By: Jon Guiton http://thoughts.davisjeff.com/2009/11/08/temporal-keys-part-2/comment-page-1/#comment-236 Jon Guiton Sat, 10 Jul 2010 14:36:49 +0000 http://thoughts.davisjeff.com/?p=180#comment-236 One concern I have for the PERIOD data type is the issue of whether the interval represented is open or closed i.e. is the endpoint included in the set of times ? In maths intervals are represented using brackets (3..4) - open, doesn't include 3 or 4, just times in between; [3..4] closed, the set of times explicitly includes 3 and 4 or mixed (3..4] 3 is not included but 4 is. This is important since in a schedule two appointments will have a gap between them if the intervals are open (2..4),(4..6) implies nothing scheduled at 4 or will overlap if tey are closed [2..4],[4..6] double booking at 4. The correct solution is to use mixed intervals e.g (2..4], (4..6] now the complete interval is covered but there is no overlap. There are many other cases where this is an issue, in fact it is an issue for any grouped data from a continuous set. If we want temporal keys to be sound we would need a solution that caters for this. One concern I have for the PERIOD data type is the issue of whether the interval represented is open or closed i.e. is the endpoint included in the set of times ? In maths
intervals are represented using brackets (3..4) – open, doesn’t include 3 or 4, just times in between; [3..4] closed, the set of times explicitly includes 3 and 4 or mixed (3..4] 3 is not included but 4 is.

This is important since in a schedule two appointments will have a gap between them if the intervals are open (2..4),(4..6) implies nothing scheduled at 4 or will overlap if tey are closed [2..4],[4..6] double booking at 4. The correct solution is to use mixed intervals e.g (2..4], (4..6] now the complete interval is covered but there is no overlap.

There are many other cases where this is an issue, in fact it is an issue for any grouped data from a continuous set. If we want temporal keys to be sound we would need a solution that caters for this.

]]>
By: BillR http://thoughts.davisjeff.com/2009/11/08/temporal-keys-part-2/comment-page-1/#comment-175 BillR Thu, 21 Jan 2010 03:19:40 +0000 http://thoughts.davisjeff.com/?p=180#comment-175 I tend to agree that millisecond precision might be overkill, but who is to know to what purpose Postgres will be put. I would not doubt that there is someone who would ask for this type of precision if you were to not provide it. ;) I know for certain that there are applications out there that definitely are down to the hour, as I found out returning my car an hour late to Avis Rent A Car. :) Anyway, I would suggest (or maybe second) the notion of finest granularity by default, and a mechanism (as you propose), to back off on the precision as needed. I tend to agree that millisecond precision might be overkill, but who is to know to what purpose Postgres will be put. I would not doubt that there is someone who would ask for this type of precision if you were to not provide it. ;) I know for certain that there are applications out there that definitely are down to the hour, as I found out returning my car an hour late to Avis Rent A Car. :)

Anyway, I would suggest (or maybe second) the notion of finest granularity by default, and a mechanism (as you propose), to back off on the precision as needed.

]]>
By: Jeff Davis http://thoughts.davisjeff.com/2009/11/08/temporal-keys-part-2/comment-page-1/#comment-133 Jeff Davis Mon, 09 Nov 2009 17:56:38 +0000 http://thoughts.davisjeff.com/?p=180#comment-133 <blockquote>PERIOD needs some more docs and test cases as well.</blockquote> Yes. I've been focusing on the core engine changes required, and Scott is working on the data types and their semantics. <blockquote>first endpoint is inclusive and the second point is exclusive</blockquote> As a default, that's fine. But there are cases where you want an inclusive end time, as well. <blockquote>Also think it would be useful to have a way to specify the granularity of the PERIOD.</blockquote> Scott had the same idea. I think this can be accomplished with a CHECK constraint, like <pre>CHECK ( first(during) = date_trunc('hour', first(during)) AND next(during) = date_trunc('hour', next(during)) )</pre> but it would be nice to make it a little easier to express.

PERIOD needs some more docs and test cases as well.

Yes. I’ve been focusing on the core engine changes required, and Scott is working on the data types and their semantics.

first endpoint is inclusive and the second point is exclusive

As a default, that’s fine. But there are cases where you want an inclusive end time, as well.

Also think it would be useful to have a way to specify the granularity of the PERIOD.

Scott had the same idea. I think this can be accomplished with a CHECK constraint, like

CHECK (
  first(during) = date_trunc('hour', first(during)) AND
  next(during) = date_trunc('hour', next(during))
)

but it would be nice to make it a little easier to express.

]]>
By: Scott Bailey http://thoughts.davisjeff.com/2009/11/08/temporal-keys-part-2/comment-page-1/#comment-132 Scott Bailey Mon, 09 Nov 2009 17:01:40 +0000 http://thoughts.davisjeff.com/?p=180#comment-132 Simon, A period defines a contiguous set of values but we can define it by the end points. The defaults are inclusive start, exclusive end. I think if you gave from() a little more thought, you'd change your mind. I agree with you on being able to define the granularity. But my thought is that it would have to be set at the database level rather than say at the column level. I'd like to generalize the concept so that we'll be able to define a range of ints, dates, timestamps, numeric, etc. Simon,

A period defines a contiguous set of values but we can define it by the end points. The defaults are inclusive start, exclusive end.

I think if you gave from() a little more thought, you’d change your mind.

I agree with you on being able to define the granularity. But my thought is that it would have to be set at the database level rather than say at the column level.

I’d like to generalize the concept so that we’ll be able to define a range of ints, dates, timestamps, numeric, etc.

]]>
By: Adrian Klaver http://thoughts.davisjeff.com/2009/11/08/temporal-keys-part-2/comment-page-1/#comment-131 Adrian Klaver Mon, 09 Nov 2009 16:05:45 +0000 http://thoughts.davisjeff.com/?p=180#comment-131 Simon, I don't know if you have access to the postgresqlconference.org site. If you do check out Scott Baileys talk on his temporal extensions to Postgres: http://www.postgresqlconference.org/2009/west/talks/temporal_data It is based on his CHRONOS project: http://sourceforge.net/projects/chronosdb/ The extensions cover some of the points you raised. Simon,
I don’t know if you have access to the postgresqlconference.org site. If you do check out Scott Baileys talk on his temporal extensions to Postgres:

http://www.postgresqlconference.org/2009/west/talks/temporal_data

It is based on his CHRONOS project:
http://sourceforge.net/projects/chronosdb/

The extensions cover some of the points you raised.

]]>
By: simon@2ndQuadrant.com http://thoughts.davisjeff.com/2009/11/08/temporal-keys-part-2/comment-page-1/#comment-130 simon@2ndQuadrant.com Mon, 09 Nov 2009 13:23:46 +0000 http://thoughts.davisjeff.com/?p=180#comment-130 Jeff, PERIOD needs some more docs and test cases as well. The docs that are there describe PERIOD as a "set" rather than as two endpoints, which is how all examples are laid out. I think a PERIOD should have two endpoints (+/- infinity included). If you have need for a more fancy datatype it can have a slightly different name. So the next() and prior() functions just look a little overcooked. Better to have just from() and to() or similar. Think it would be useful to have the default as the first endpoint is inclusive and the second point is exclusive, so they stack together neatly by default. Also think it would be useful to have a way to specify the granularity of the PERIOD. In many cases a period is expressed only in days, not timestamps. For example in your hotel room example you don't book a hotel room for an exact second, you book one night at a time. Of course, some hotels do book by the hour, but very few by the second. It wouldn't be much use for businesses to refuse a booking because there was a 10ms overlap between 2 5 day bookings - nor would anybody really want to record that detail. So perhaps we need DATEPERIOD (2 DATEs) and TIMEPERIOD (2 TIMESTAMPs). It might be useful to be able to specify this like PERIOD(INTERVAL), so you can book holiday cottages in weeks, scaffolding by month etc.. Whatever the business needs. Jeff,

PERIOD needs some more docs and test cases as well.

The docs that are there describe PERIOD as a “set” rather than as two endpoints, which is how all examples are laid out. I think a PERIOD should have two endpoints (+/- infinity included). If you have need for a more fancy datatype it can have a slightly different name. So the next() and prior() functions just look a little overcooked. Better to have just from() and to() or similar.

Think it would be useful to have the default as the first endpoint is inclusive and the second point is exclusive, so they stack together neatly by default.

Also think it would be useful to have a way to specify the granularity of the PERIOD. In many cases a period is expressed only in days, not timestamps. For example in your hotel room example you don’t book a hotel room for an exact second, you book one night at a time. Of course, some hotels do book by the hour, but very few by the second. It wouldn’t be much use for businesses to refuse a booking because there was a 10ms overlap between 2 5 day bookings – nor would anybody really want to record that detail.

So perhaps we need DATEPERIOD (2 DATEs) and TIMEPERIOD (2 TIMESTAMPs). It might be useful to be able to specify this like PERIOD(INTERVAL), so you can book holiday cottages in weeks, scaffolding by month etc.. Whatever the business needs.

]]>
By: simon@2ndQuadrant.com http://thoughts.davisjeff.com/2009/11/08/temporal-keys-part-2/comment-page-1/#comment-129 simon@2ndQuadrant.com Mon, 09 Nov 2009 13:11:22 +0000 http://thoughts.davisjeff.com/?p=180#comment-129 Tom, interesting post. Good solutions thinking. The trigger method, as described, doesn't correctly handle concurrent inserts. That illustrates my main concern which is that there is too much code there and it is likely to have errors - I think you showed that in the number of posts taken as well. Anyhow, it is certainly slower than the in-database approach Jeff has designed. Tom, interesting post. Good solutions thinking.

The trigger method, as described, doesn’t correctly handle concurrent inserts. That illustrates my main concern which is that there is too much code there and it is likely to have errors – I think you showed that in the number of posts taken as well. Anyhow, it is certainly slower than the in-database approach Jeff has designed.

]]>
By: Tom Davis http://thoughts.davisjeff.com/2009/11/08/temporal-keys-part-2/comment-page-1/#comment-128 Tom Davis Mon, 09 Nov 2009 09:40:08 +0000 http://thoughts.davisjeff.com/?p=180#comment-128 Wow! I did it again! CREATE OR REPLACE FUNCTION dont_overlap_reservations() RETURNS trigger AS $$ DECLARE overlaps text; BEGIN SELECT whom INTO overlaps FROM room_reservation WHERE room = NEW.room AND beginning <= NEW.until AND until >= NEW.beginning LIMIT 1; IF FOUND THEN RETURN NULL; ELSE RETURN NEW; END IF; END; $$ LANGUAGE plpgsql; Wow! I did it again!

CREATE OR REPLACE FUNCTION dont_overlap_reservations() RETURNS trigger AS $$
DECLARE
overlaps text;
BEGIN
SELECT whom INTO overlaps
FROM room_reservation
WHERE room = NEW.room
AND beginning <= NEW.until
AND until >= NEW.beginning
LIMIT 1;
IF FOUND THEN
RETURN NULL;
ELSE
RETURN NEW;
END IF;
END;
$$ LANGUAGE plpgsql;

]]>
By: Tom Davis http://thoughts.davisjeff.com/2009/11/08/temporal-keys-part-2/comment-page-1/#comment-127 Tom Davis Mon, 09 Nov 2009 09:38:56 +0000 http://thoughts.davisjeff.com/?p=180#comment-127 Sorry, forgot to escape the greater than and less than operators, the function should be CREATE OR REPLACE FUNCTION dont_overlap_reservations() RETURNS trigger AS $$ DECLARE overlaps text; BEGIN SELECT whom INTO overlaps FROM room_reservation WHERE room = NEW.room AND beginning = NEW.beginning LIMIT 1; IF FOUND THEN RETURN NULL; ELSE RETURN NEW; END IF; END; $$ LANGUAGE plpgsql; Plus, obviously, you would use a timestamp rather than a time, and it's probably a good idea to declare (room,beginning,until) as the primary key. For more than five rows an index might be useful. Sorry, forgot to escape the greater than and less than operators, the function should be

CREATE OR REPLACE FUNCTION dont_overlap_reservations() RETURNS trigger AS $$
DECLARE
overlaps text;
BEGIN
SELECT whom INTO overlaps
FROM room_reservation
WHERE room = NEW.room
AND beginning = NEW.beginning
LIMIT 1;
IF FOUND THEN
RETURN NULL;
ELSE
RETURN NEW;
END IF;
END;
$$ LANGUAGE plpgsql;

Plus, obviously, you would use a timestamp rather than a time,

and it’s probably a good idea to declare (room,beginning,until) as the primary key. For more than five rows an index might be useful.

]]>