Re: Advice on foreign key and cascading delete design - postgresql 12.6 - Mailing list pgsql-novice
From | Steve Tucknott (TuSol) |
---|---|
Subject | Re: Advice on foreign key and cascading delete design - postgresql 12.6 |
Date | |
Msg-id | b047654785ee3f4f8ea1e6e948bfa22563baeed1.camel@tusol.co.uk Whole thread Raw |
In response to | Re: Advice on foreign key and cascading delete design - postgresql 12.6 (Bzzzz <lazyvirus@gmx.com>) |
Responses |
Re: Advice on foreign key and cascading delete design - postgresql 12.6
|
List | pgsql-novice |
On Wed, 2021-04-14 at 14:27 +0200, Bzzzz wrote:
Oh I missed that, ok, in this case, you need to do 2 things :* add "join" tables with only 2 columns :* a RI to 'main1' (or main2, etc, one table per father)* a RI to 'dependency'with ON DELETE CASCADE|create table schema.main1_dependency(int not null references schema.main1(id) on delete cascadeint not null references schema.dependency(id))* a trigger for each of these tables that'll delete the concerned'dependency' rows when a row is deleted from one of these tables(of course, that means you _must_ embed all this into a transaction.)|Note that, if it is what you're looking for, you should be able to…cascade the deletion - ie: you delete a row from 'main5', which, bycascade will delete all pointing rows from a 'main5_dependency' and thetrigger will, at last, delete pointing rows from 'dependency'.Looks like that : main1 <--- main1_dependency ---> dependencymain2 <--- main2_dependency ---> dependency…Creation:[if row doesn't exist into 'main1', transaction may starts here]* create row into 'main1' (ie: 4798)[if row does exist into 'main1', transaction starts here]* create row into 'dependency' (ie: 15025)* create row into 'main1_dependency' to materialize the link(ie: ri_main1=2798 & ri_dependency=15025)[commit|rollback]Caution: if all of these steps are in only one transaction, you'll haveto defer to avoid errors !Deletion:delete from 'main1' where id=4798CASCADE, deleting from 'main1_dependency' where ri_main1=4798which launch trigger that will delete all rows from 'dependency'when main1_dependency(ri_main1)=4798My structure handles that as the 'dependency' tablealso carries the table name of the 'main' - so I could have rows ondependency of:1,'some text for main', 1,'main'2,'some text formain2',1,'main2'3,'some text for main3',1,'main3'.....etcBut the the FKback to main[123] is composed of two parts - the ID and the tablename.Bad design, because that means you must have a RI column for each andevery 'mainN' table into 'dependency' - will works if N < 10, butwill start to be a mess when N > 20, unusable if N ≥ 1000.
Thanks Jean-Yves, that makes more sense - although I do find 'normalised' structures slightly frustrating even though I can see that the structure works.
You say that it's bad design having the foreigntablename on the dependency as it's not practical if the number of dependent tables is large, but why is it any better then having many 'intermediate main-to-dependency' tables?
I think I've gone full circle in that I currently control the orphans via hand cranked code - but I hadn't functionalised it. It seems that another option is to make the tidy up generic by using the information schemas in a function that purges all records that carry a 'foreigntablename' and 'foreignrecno' for the main table.
Thanks again for the time and effort you've put into explaining this for me.
Regards,
Steve
pgsql-novice by date: