Comments on: Exclusion Constraints are generalized SQL UNIQUE http://thoughts.davisjeff.com/2010/09/25/exclusion-constraints-are-generalized-sql-unique/ 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: Gary Clarke http://thoughts.davisjeff.com/2010/09/25/exclusion-constraints-are-generalized-sql-unique/comment-page-1/#comment-1364 Gary Clarke Tue, 05 Oct 2010 14:44:11 +0000 http://thoughts.davisjeff.com/?p=321#comment-1364 I've recently started looking at PostgreSQL closely and I am very excited by your work on Temporal support in the Database. In MS SQL Server I created constraints that called User Defined Functions - to check for Overlap/ Abut/ Contains for Period Ranges. These seemed to work OK in my Dev environment, but I’m not sure how practical would be in production. Your Exclusion Constraints look perfect for preventing Overlap in a fast efficient manner – What do you suggest for Foreign Key Includes? Is it practical to use a Function called by a Constraint in PostgreSQL, to enforce this (I would prefer this to Triggers) ? Can I use the Geometric Contains Operator (after converting Periods to Integers via a Calendar table) ? I got excited when I saw the Interval Data Type (not in SQL server) – but then was disappointed when I saw that it lacks a Contains Operator ??? Your Period Type appears to resolve this, but I have found it impossible to install on Windows – any help or clues for installing on Windows for version 9.0 would be very much appreciated, do I need to re-install PostgreSQL from Source Code - Instead of from enterprisedb Installer. If I purchase PostgrePlus would this help ? – does not appear to be version 9.0 though. If you could please send me some clues or pointers – I will be eternally grateful Gary Clarke CEO M4 Systems Ltd I’ve recently started looking at PostgreSQL closely and I am very excited by your work on Temporal support in the Database.
In MS SQL Server I created constraints that called User Defined Functions – to check for Overlap/ Abut/ Contains for Period Ranges. These seemed to work OK in my Dev environment, but I’m not sure how practical would be in production.
Your Exclusion Constraints look perfect for preventing Overlap in a fast efficient manner – What do you suggest for Foreign Key Includes? Is it practical to use a Function called by a Constraint in PostgreSQL, to enforce this (I would prefer this to Triggers) ? Can I use the Geometric Contains Operator (after converting Periods to Integers via a Calendar table) ?
I got excited when I saw the Interval Data Type (not in SQL server) – but then was disappointed when I saw that it lacks a Contains Operator ???
Your Period Type appears to resolve this, but I have found it impossible to install on Windows – any help or clues for installing on Windows for version 9.0 would be very much appreciated, do I need to re-install PostgreSQL from Source Code – Instead of from enterprisedb Installer. If I purchase PostgrePlus would this help ? – does not appear to be version 9.0 though.
If you could please send me some clues or pointers – I will be eternally grateful
Gary Clarke CEO M4 Systems Ltd

]]>
By: Jeff Davis http://thoughts.davisjeff.com/2010/09/25/exclusion-constraints-are-generalized-sql-unique/comment-page-1/#comment-1354 Jeff Davis Mon, 27 Sep 2010 15:39:17 +0000 http://thoughts.davisjeff.com/?p=321#comment-1354 I'm not a windows developer, but I can't see why it wouldn't work on windows if you have a compiler. The PERIOD type uses PGXS, so I'd recommend searching around for "PGXS windows". I’m not a windows developer, but I can’t see why it wouldn’t work on windows if you have a compiler. The PERIOD type uses PGXS, so I’d recommend searching around for “PGXS windows”.

]]>
By: Richard Broersma Jr. http://thoughts.davisjeff.com/2010/09/25/exclusion-constraints-are-generalized-sql-unique/comment-page-1/#comment-1351 Richard Broersma Jr. Mon, 27 Sep 2010 04:07:09 +0000 http://thoughts.davisjeff.com/?p=321#comment-1351 I certainly looking forward to range types being added. Jeff, do you have any direction for us windows users out there on how to add the period type to a windows build? I certainly looking forward to range types being added. Jeff, do you have any direction for us windows users out there on how to add the period type to a windows build?

]]>
By: David Fetter http://thoughts.davisjeff.com/2010/09/25/exclusion-constraints-are-generalized-sql-unique/comment-page-1/#comment-1349 David Fetter Sun, 26 Sep 2010 19:15:53 +0000 http://thoughts.davisjeff.com/?p=321#comment-1349 Oops. The HTML-swallower made my constraint look silly. It should be CHECK(professor <> student) Oops. The HTML-swallower made my constraint look silly. It should be

CHECK(professor <> student)

]]>
By: David Fetter http://thoughts.davisjeff.com/2010/09/25/exclusion-constraints-are-generalized-sql-unique/comment-page-1/#comment-1348 David Fetter Sun, 26 Sep 2010 19:14:28 +0000 http://thoughts.davisjeff.com/?p=321#comment-1348 You can do cycles of length 2 with this constraint: CHECK(professor student), /* Assuming neither can be NULL */ UNIQUE(LEAST(professor, student), GREATEST(professor, student)) I'm working on a way to handle arbitrarily long cycles that may involve EXCLUDE constraints, or may not. In the end, something has to do something equivalent to restricting the transitive closure. You can do cycles of length 2 with this constraint:

CHECK(professor student), /* Assuming neither can be NULL */
UNIQUE(LEAST(professor, student), GREATEST(professor, student))

I’m working on a way to handle arbitrarily long cycles that may involve EXCLUDE constraints, or may not. In the end, something has to do something equivalent to restricting the transitive closure.

]]>
By: Jeff Davis http://thoughts.davisjeff.com/2010/09/25/exclusion-constraints-are-generalized-sql-unique/comment-page-1/#comment-1346 Jeff Davis Sun, 26 Sep 2010 16:22:59 +0000 http://thoughts.davisjeff.com/?p=321#comment-1346 To answer your question directly, if you'd like to prevent a bidirectional relationship, you can use a UNIQUE constraint on a functional index, where the index function puts the elements in a canonical form. For instance, if you have a function f(x,y): if x > y then y::text || ',' || x::text else x::text || ',' || y::text end Put a functional UNIQUE index on that, and it will prevent the bidirectional relationships. However, that won't prevent cycles (a->b->c->a). To prevent cycles, you might need to use some other trick, like saying that a parent ID is always less than a child ID. You might want the constraint that a child only has one parent, as well, to make it more tree-like. Also, the two UNIQUE constraints you have in your example are redundant. One implies the other. To answer your question directly, if you’d like to prevent a bidirectional relationship, you can use a UNIQUE constraint on a functional index, where the index function puts the elements in a canonical form. For instance, if you have a function
f(x,y):
if x > y then y::text || ‘,’ || x::text
else x::text || ‘,’ || y::text end

Put a functional UNIQUE index on that, and it will prevent the bidirectional relationships.

However, that won’t prevent cycles (a->b->c->a). To prevent cycles, you might need to use some other trick, like saying that a parent ID is always less than a child ID.

You might want the constraint that a child only has one parent, as well, to make it more tree-like.

Also, the two UNIQUE constraints you have in your example are redundant. One implies the other.

]]>
By: Jeff Davis http://thoughts.davisjeff.com/2010/09/25/exclusion-constraints-are-generalized-sql-unique/comment-page-1/#comment-1345 Jeff Davis Sun, 26 Sep 2010 15:58:55 +0000 http://thoughts.davisjeff.com/?p=321#comment-1345 Peter was of a similar opinion. What really killed that idea, for me at least, was that exclusion constraints can express constraints that are the *opposite* of UNIQUE: Consider the <> operator, which satisfies the necessary criteria, and will be the subject of a future post. Also, we discussed the matter at length. I think that using the word UNIQUE would have led to superficial understanding, at best. When I get Range Types in, then we can add some syntax sugar for a "range key" that is more intuitive for the common case (temporal keys). Peter was of a similar opinion. What really killed that idea, for me at least, was that exclusion constraints can express constraints that are the *opposite* of UNIQUE: Consider the <> operator, which satisfies the necessary criteria, and will be the subject of a future post.

Also, we discussed the matter at length. I think that using the word UNIQUE would have led to superficial understanding, at best. When I get Range Types in, then we can add some syntax sugar for a “range key” that is more intuitive for the common case (temporal keys).

]]>
By: Joe http://thoughts.davisjeff.com/2010/09/25/exclusion-constraints-are-generalized-sql-unique/comment-page-1/#comment-1344 Joe Sun, 26 Sep 2010 13:53:51 +0000 http://thoughts.davisjeff.com/?p=321#comment-1344 Let's say you have a relationship table between two entities. Usually, you could say that one of the entities is "superior" to the other, for example, a parent to a child, a group to its members, but even if that is semantically expressed in the design, the UNIQUE constraints cannot control the insertion of a duplicate reverse relationship. For example, CREATE TABLE mentors (professor integer, student integer, ...); ALTER TABLE mentors ADD UNIQUE (professor, student); ALTER TABLE mentors ADD UNIQUE (student, professor); INSERT INTO mentors VALUES (1,2); INSERT INTO mentors VALUES (2,1); Assuming you don't want to allow the second tuple, can an EXCLUDE constraint be used to achieve that? Let’s say you have a relationship table between two entities. Usually, you could say that one of the entities is “superior” to the other, for example, a parent to a child, a group to its members, but even if that is semantically expressed in the design, the UNIQUE constraints cannot control the insertion of a duplicate reverse relationship. For example,

CREATE TABLE mentors (professor integer, student integer, …);
ALTER TABLE mentors ADD UNIQUE (professor, student);
ALTER TABLE mentors ADD UNIQUE (student, professor);
INSERT INTO mentors VALUES (1,2);
INSERT INTO mentors VALUES (2,1);

Assuming you don’t want to allow the second tuple, can an EXCLUDE constraint be used to achieve that?

]]>
By: David Wheeler http://thoughts.davisjeff.com/2010/09/25/exclusion-constraints-are-generalized-sql-unique/comment-page-1/#comment-1343 David Wheeler Sun, 26 Sep 2010 02:46:46 +0000 http://thoughts.davisjeff.com/?p=321#comment-1343 Reading this, I now kinda wish that the `UNIQUE` keyword had been extended, rather than adding the new keyword `EXCLUDE`, which frankly is kind of a confusing term. Powerful feature, though. Thanks! David Reading this, I now kinda wish that the `UNIQUE` keyword had been extended, rather than adding the new keyword `EXCLUDE`, which frankly is kind of a confusing term.

Powerful feature, though. Thanks!

David

]]>