Re: unreferenced primary keys: garbage collection - Mailing list pgsql-sql

From Jan Wieck
Subject Re: unreferenced primary keys: garbage collection
Date
Msg-id 200101222219.RAA15009@jupiter.jw.home
Whole thread Raw
In response to Re: unreferenced primary keys: garbage collection  (Jan Wieck <janwieck@Yahoo.com>)
Responses Re: unreferenced primary keys: garbage collection  (Forest Wilkinson <fspam@home.com>)
List pgsql-sql
Jan Wieck wrote:
> Forest Wilkinson wrote:
> > I have a database in which five separate tables may (or may not) reference
> > any given row in a table of postal addresses.  I am using the primary /
> > foreign key support in postgres 7 to represent these references.
> >
> > My problem is that, any time a reference is removed (either by deleting or
> > updating a row in one of the five referencing tables), no garbage
> > collection is being performed on the address table.  That is, when the
> > last reference to an address record goes away, the record is not removed
> > from the address table.  Over time, my database will fill up with
> > abandoned address records.
>
>     While  this  behaviour  makes  sense  in  your case, it's not
>     subject  to  referential  integrity  constraints.  You  could
>     arrange  for  it with custom trigger procedures, checking all
>     the five tables on DELETE or UPDATE on one of them.
>
>     I'll make up a little example and post it  the  other  day  -
>     need  to  take  a  nap  now and tomorrow will be one of these
>     30-hour days (from MET to  EST),  so  don't  expect  anything
>     before Monday afternoon (EST).
   Here it is:
        CREATE TABLE t_addr (            a_id        integer PRIMARY KEY,            a_name      text        );
        CREATE TABLE t_customer (            c_id        integer PRIMARY KEY,            c_address   integer REFERENCES
t_addr       );
 
        CREATE TABLE t_order (            o_id        integer PRIMARY KEY,            o_customer  integer REFERENCES
t_customer                               ON DELETE CASCADE,            o_shipaddr  integer REFERENCES t_addr        );
 
        CREATE FUNCTION tidy_up_addr(integer) RETURNS bool AS '        DECLARE            chk_addr    ALIAS FOR $1;
  BEGIN            --            -- Check if address is still referenced from t_customer            --            IF
count(c_address)> 0 FROM t_customer                        WHERE c_address = chk_addr            THEN
RETURN''f'';            END IF;            --            -- Check if address is still referenced from t_order
--            IF count(o_shipaddr) > 0 FROM t_order                        WHERE o_shipaddr = chk_addr            THEN
             RETURN ''f'';            END IF;            --            -- Address not required any more - get rid of
it.           --            DELETE FROM t_addr WHERE a_id = chk_addr;            RETURN ''t'';        END;        '
LANGUAGE'plpgsql';
 
        CREATE FUNCTION customer_upd_or_del() RETURNS opaque AS '        BEGIN            PERFORM
tidy_up_addr(old.c_address);           RETURN NULL;        END;        ' LANGUAGE 'plpgsql';
 
        CREATE TRIGGER customer_upd_or_del            AFTER UPDATE OR DELETE ON t_customer            FOR EACH ROW
EXECUTEPROCEDURE customer_upd_or_del();
 
        CREATE FUNCTION order_upd_or_del() RETURNS opaque AS '        BEGIN            PERFORM
tidy_up_addr(old.o_shipaddr);           RETURN NULL;        END;        ' LANGUAGE 'plpgsql';
 
        CREATE TRIGGER order_upd_or_del            AFTER UPDATE OR DELETE ON t_order            FOR EACH ROW EXECUTE
PROCEDUREorder_upd_or_del();
 
   We  have  two  tables  referencing the address table. Each of   get's it's own trigger, simply calling the  tidy-up
function  that  removes  the  address  if it's not referenced any more.   Thus, adding a 3rd referencing table to the
schema needs  to   add  the  check for reference to one central function, plus a   very simple trigger on the new
table. Hope  this  works  for   you.
 


Have fun, Jan

--

#======================================================================#
# It's easier to get forgiveness for being wrong than for being right. #
# Let's break this rule - forgive me.                                  #
#================================================== JanWieck@Yahoo.com #



_________________________________________________________
Do You Yahoo!?
Get your free @yahoo.com address at http://mail.yahoo.com



pgsql-sql by date:

Previous
From: Michael Davis
Date:
Subject: RE: Joining several tables
Next
From: Bruce Momjian
Date:
Subject: Re: Re: is there a mysql to postgresql sql converter?