Обсуждение: 1 to many relationships
If I have a child table and a parent table like so:
---BEGIN TABLE DEFS---------------------------------------------
create table parents(
PriKey serial
);
add primary constraint to PriKey;
create table child(
parent INT4 NOT NULL
);
add foreign key constraint parent refs parent.PriKey ON DELETE CASCADE;
---BEGIN RELATIONSHIP DEF----------------------------------------
They are supposed to have the following relationship:
parent(1T1)<------->(1TM)children
textually explained as 'One parent has many children and must have at
least one in order to exist, while a child must have one and only one
parent in order to exist')
---BEGIN PROBLEM DEF / QUESTION --------=------------------------
For the 1T1 side of the relationship:
the table defs will automatically cause the children to be caught or
killed in the event that their parents disappear, no prob.
For the 1TM side of the relationship:
I don't see anything in the docs that says the PARENT will be
sacrificed if their children don't survive or disappear, and I don't
even know if there exists in any database the table definition option to
enforce this.
How is this done on different DB's? On Postgres?
---BEGIN GUESS---------------------------------------------------
Triggers?
--
Carpe Dancem ;-)
-----------------------------------------------------------------
Remember your friends while they are alive
-----------------------------------------------------------------
Sincerely, Dennis Gearon
You cannot do that with 'standard' sql. The problem is that when you are deleting a child, there is no simple way tell whether it was the last entry remaining that still references the parent... You can create a custom trigger on the child table, that would do what you want... I don't know the syntax of plpgslq (normally write stuff like that in C), so I cannot juts give you the sample code... But the idea is something like create function cascade_on_parent () returns opaque as ' begin delete from parent where prikey=old.parent and not exists (select 1 from child where parent=old.parent limit 1); return null; end; ' language 'plpgsql'; And then you do create constraint trigger cascade_parent after delete or update on child initially deferred for each row execute procedure cascade_on_parent (); I hope, it helps... Dima Dennis Gearon wrote: > If I have a child table and a parent table like so: > > ---BEGIN TABLE DEFS--------------------------------------------- > create table parents( > PriKey serial > ); > add primary constraint to PriKey; > > create table child( > parent INT4 NOT NULL > ); > add foreign key constraint parent refs parent.PriKey ON DELETE CASCADE; > > > > ---BEGIN RELATIONSHIP DEF---------------------------------------- > They are supposed to have the following relationship: > > parent(1T1)<------->(1TM)children > > textually explained as 'One parent has many children and must have at > least one in order to exist, while a child must have one and only one > parent in order to exist') > > > > ---BEGIN PROBLEM DEF / QUESTION --------=------------------------ > For the 1T1 side of the relationship: > the table defs will automatically cause the children to be caught or > killed in the event that their parents disappear, no prob. > > For the 1TM side of the relationship: > I don't see anything in the docs that says the PARENT will be > sacrificed if their children don't survive or disappear, and I don't > even know if there exists in any database the table definition option to > enforce this. > > > How is this done on different DB's? On Postgres? > > > ---BEGIN GUESS--------------------------------------------------- > Triggers? > > >
??????? ???????, ????! Bolshoi Spaciba, Dima, thank you very much Dima! I will reply to your other letter later today. 2/23/2003 9:30:40 AM, Dima Tkach <dmitry@openratings.com> wrote: >You cannot do that with 'standard' sql. > >The problem is that when you are deleting a child, there is no simple >way tell whether it was the last entry remaining that still references >the parent... > >You can create a custom trigger on the child table, that would do what >you want... >I don't know the syntax of plpgslq (normally write stuff like that in >C), so I cannot juts give you the sample code... But the idea is >something like > >create function cascade_on_parent () returns opaque as ' >begin >delete from parent where prikey=old.parent and >not exists (select 1 from child where parent=old.parent limit 1); >return null; >end; >' language 'plpgsql'; > > >And then you do > >create constraint trigger cascade_parent after delete or update on child >initially deferred for each row execute procedure cascade_on_parent (); > >I hope, it helps... > >Dima > > > >Dennis Gearon wrote: >> If I have a child table and a parent table like so: >> >> ---BEGIN TABLE DEFS--------------------------------------------- >> create table parents( >> PriKey serial >> ); >> add primary constraint to PriKey; >> >> create table child( >> parent INT4 NOT NULL >> ); >> add foreign key constraint parent refs parent.PriKey ON DELETE CASCADE; >> >> >> >> ---BEGIN RELATIONSHIP DEF---------------------------------------- >> They are supposed to have the following relationship: >> >> parent(1T1)<------->(1TM)children >> >> textually explained as 'One parent has many children and must have at >> least one in order to exist, while a child must have one and only one >> parent in order to exist') >> >> >> >> ---BEGIN PROBLEM DEF / QUESTION --------=------------------------ >> For the 1T1 side of the relationship: >> the table defs will automatically cause the children to be caught or >> killed in the event that their parents disappear, no prob. >> >> For the 1TM side of the relationship: >> I don't see anything in the docs that says the PARENT will be >> sacrificed if their children don't survive or disappear, and I don't >> even know if there exists in any database the table definition option to >> enforce this. >> >> >> How is this done on different DB's? On Postgres? >> >> >> ---BEGIN GUESS--------------------------------------------------- >> Triggers? >> >> >> > > >---------------------------(end of broadcast)--------------------------- >TIP 4: Don't 'kill -9' the postmaster >