Search Postgresql Archives

Re: complex referential integrity constraints

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



>-----Original Message-----
>From: Robert Haas [mailto:Robert.Haas@xxxxxxxxxx] 
>Sent: donderdag 22 februari 2007 15:58
>To: Joris Dobbelsteen; elein
>Cc: pgsql-general@xxxxxxxxxxxxxx
>Subject: RE: [GENERAL] complex referential integrity constraints
>
>The ability to make a foreign key reference a specific partial 
>unique index (rather than just a set of columns that have a 
>unique index) would solve many problems of this type.  As 
>another example, you might have a table where one of the 
>columns is "is_deleted boolean not null".  By creating a 
>partial unique index on the primary key of that table "WHERE 
>NOT is_deleted" and then pointing a foreign key at it, you 
>could enforce that each row in the child table references a 
>parent who isn't deleted.
>
>However, this would break down when there's more one than 
>intermediate step involved.  For example, if you have:
>
>CREATE TABLE animal_type (
>      id			serial,
>	name			varchar(60) not null,
>	is_attacker		boolean not null,
>	primary key (id)
>);
>
>CREATE TABLE animal (
>	id			serial,
>	type_id		integer not null references animal_type (id),
>	name			varchar(60) not null,
>	primary key (id)
>);
>
>CREATE TABLE mauling (
>	id			serial,
>	attacker_id		integer not null references animal (id),
>	victim_id		integer not null references animal (id),
>	attack_time		timestamp with time zone not null,
>	primary key (id)
>);
>
>It would be easy to enforce the constraint that the attacker 
>must be an animal of some specific type, but difficult to 
>enforce the constraint that the attacker must be an animal 
>whose type, in turn, has a true value for is_attacker.

Even worse, I don't you can guarentee that this constraint is enforced
at all times. That means, not if you are using triggers.
The only option seems using foreign keys and put in a lot of redundant
data.

>The best idea that I can think of right now to handle multiple 
>levels of tables is to allow FOREIGN KEY constraints to 
>references a VIEW, rather than a table.  Then you could say:
>
>CREATE VIEW attackers AS
>SELECT a.id FROM animal a, animal_type t WHERE a.type_id = 
>t.id AND t.attacker;
>
>...and then FOREIGN KEY (attacker_id) REFERENCES attackers (id).

Perhaps "Alban Hertroys" idea solves this problem a little easier.
However it lacks the possibility to make quick changes later on
(predator is a predator, or you are screwed, no second change).
This is not acceptable in problems where such things are decided after
object creation or might be changed later on.

>This syntax would solve a number of other problems as well, 
>such as requiring that some record in table A has a parent 
>either in table P or in table Q. However, I think this would 
>probably require implementing some kind of materialized view 
>so that you could actually build an index on the view, and 
>that opens up a whole new can of worms, because it's not very 
>difficult to define a view that is costly to update incrementally.

You don't need a materialized view to put a database to its knees. You
can already do that today, with ease. I wouldn't worry too much about
that.
If you mean from a syntax I suggested I do not believe it's the 'right'
way to define an (materialized) view, rather use a trigger-like style of
system. There are some other issues, however.

>The problem is really that there is a pretty large gap between 
>writing a foreign key constraint, which is trivial, and 
>enforcing a constraint using triggers, which is quite a bit 
>more complex (and therefore, easy to screw up), because the 
>foreign key automatically handles all the cases (insert into 
>child table, update of child table, update of parent table, 
>delete from parent table) whereas with triggers you have to 
>address each of those cases individually.

Exactly, that is why I suggested such a system. If its not easy to
enforce constraints, it will never happen properly. Especially if
problems get more complex.

>Unfortunately, 
>something tells me that implementing a more powerful system 
>for foreign key constraints is a non-trivial project, however 
>useful it would be.
>Still, I'd love to see it in the TODO file, too.

Me too, I get the impression that SQL is too weak for most constraints.

- Joris

>...Robert
>
>-----Original Message-----
>From: Joris Dobbelsteen [mailto:Joris@xxxxxxxxxxxxxxxxxxxxx]
>Sent: Thursday, February 22, 2007 8:03 AM
>To: Robert Haas; elein
>Cc: pgsql-general@xxxxxxxxxxxxxx
>Subject: RE: [GENERAL] complex referential integrity constraints
>
>I partially agree:
>If people CAN do stupid things, they are 'clever' enough to 
>find a way to actually do it. I've seen them destroy things, 
>by just using a system in a way it was not intended. They 
>effectively found a way to blow away the very thing that part 
>was designed for.
>But indeed, it's a lot of work, especially if the number of 
>tables that must be referenced increases. I'm a strong 
>supporter for ensuring consistency. Postgres has what it takes 
>to do the job, but it doesn't make my life a lot easier. But 
>it seems to be as good as it gets today...
>
>Perhaps we should rather define a 'database' constraint in the 
>order of:
>"For every mauling, the attacking animal must be of the attacker type"
>(in a computer understandable manner). From the set theory 
>this should be possible without too much problems, However 
>doing so efficiently might be slightly harder.
>This might be a fun project and useful for the TODO list. At 
>least it makes it a lot easier (and maintanable) to enforce 
>database-wide constraints.
>
>- Joris
>
>>-----Original Message-----
>>From: Robert Haas [mailto:Robert.Haas@xxxxxxxxxx]
>>Sent: woensdag 21 februari 2007 3:37
>>To: Joris Dobbelsteen; elein
>>Cc: pgsql-general@xxxxxxxxxxxxxx
>>Subject: RE: [GENERAL] complex referential integrity constraints
>>
>>Yes, exactly.  And while you might not care about all of 
>those (e.g. I 
>>care about the first two but am not worried about the third 
>one because 
>>I'm the only one who will ever update that table), writing multiple 
>>triggers to enforce each constraint of this type quickly gets old if 
>>there are even a few of them.
>> It is exponentially harder to write a constraint of this 
>type than it 
>>is to write a simple foreign key constraint.
>>
>>...Robert
>>
>>-----Original Message-----
>>From: Joris Dobbelsteen [mailto:Joris@xxxxxxxxxxxxxxxxxxxxx]
>>Sent: Monday, February 19, 2007 5:59 AM
>>To: elein; Robert Haas
>>Cc: pgsql-general@xxxxxxxxxxxxxx
>>Subject: RE: [GENERAL] complex referential integrity constraints
>>
>>>Why don't you add a field in animal_types that is boolean mauler.
>>>Then you can add a trigger on the mauling table to raise an
>>error when
>>>the attacker_id is an animal type mauler.
>>
>>This is only partial. You need a lot more triggers to guarentee the 
>>constraints are enforced.
>>Precisely you need to validate:
>>* mauling on insert/update of attacker_id
>>* animal on update of type_id
>>* animal_type on update of your property
>>
>>Of course you need to think about the MVCC model, such that:
>>Transaction 1 executes
>>INSERT INTO mauling VALUES ('someattacker'), Transaction 2 executes 
>>UPDATE animal_type SET mauler = false WHERE name = 
>'someattacker', such 
>>that both transaction happen in parallel.
>>
>>This is perfectly possible and will make it possible to violate the 
>>constraint, UNLESS locking of the tuples is done correctly.
>>
>>These contraints are not trivial to implement (unfortunally). 
>>It would be great if they where.
>>
>>- Joris
>>
>


[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Index of Archives]     [Postgresql Jobs]     [Postgresql Admin]     [Postgresql Performance]     [Linux Clusters]     [PHP Home]     [PHP on Windows]     [Kernel Newbies]     [PHP Classes]     [PHP Books]     [PHP Databases]     [Postgresql & PHP]     [Yosemite]
  Powered by Linux