Обсуждение: how to know when a table is altered

Поиск
Список
Период
Сортировка

how to know when a table is altered

От
"Vincenzo Passoli"
Дата:
i'm developing a framework (mod_perl+apache) that reads the db-schema and 
explode html forms.

now i read the schema and cache it into perl-hashes to speedup things.

my problem is to recognise when a table is altered so that the framework can 
update the related forms connected to the db tables.
i don't want to read the schema every time.

How can i implement this ?


thank you in advance for your help
valter, italy
________________________________________________________________________
Get Your Private, Free E-mail from MSN Hotmail at http://www.hotmail.com



Re: how to know when a table is altered

От
Ed Loehr
Дата:
Vincenzo Passoli wrote:
> 
> i'm developing a framework (mod_perl+apache) that reads the db-schema and
> explode html forms.
> 
> now i read the schema and cache it into perl-hashes to speedup things.
> 
> my problem is to recognise when a table is altered so that the framework can
> update the related forms connected to the db tables.
> i don't want to read the schema every time.
> 
> How can i implement this ?

My sub-optimal approach was to cache all of the generally static tables
(requiring a restart to reload them if they changed), and query the
rest.  You can avoid a lot of joins by querying the db for the foreign
keys to static tables and then looking them up only in the app cache. 
But caching query results and invalidating them when the underlying
tables changed would greatly simplify my app and speed things up, so I'd
love to hear if others have a better/faster solution here.

Regards,
Ed Loehr


Re: how to know when a table is altered

От
Ed Loehr
Дата:
Ed Loehr wrote:
> 
> Vincenzo Passoli wrote:
> >
> > i'm developing a framework (mod_perl+apache) that reads the db-schema and
> > explode html forms.
> >
> > now i read the schema and cache it into perl-hashes to speedup things.
> >
> > my problem is to recognise when a table is altered so that the framework can
> > update the related forms connected to the db tables.
> > i don't want to read the schema every time.
> >
> > How can i implement this ?
> 
> My sub-optimal approach was to cache all of the generally static tables
> (requiring a restart to reload them if they changed), and query the
> rest.  You can avoid a lot of joins by querying the db for the foreign
> keys to static tables and then looking them up only in the app cache.
> But caching query results and invalidating them when the underlying
> tables changed would greatly simplify my app and speed things up, so I'd
> love to hear if others have a better/faster solution here.

I was thinking about another possible approach (and definitely
half-baked).  I'd call it "table-based caching".  Suppose you created a
table specifically for tracking how recently a table had been updated,
e.g.,
create table table_status (    tablename    varchar not null unique,    last_change    timestamp not null);

Then create triggers for every table that updated
table_status.last_change = now() on every UPDATE/DELETE/INSERT.  Then, to
determine when you need to invalidate the application cache, you'd load
this table at the beginning of the request and invalidate cache entries
involving tables with table_status.last_change more recent than when the
query results were cached.  

If, like most DBs yours is mostly reads, you'd suffer one pretty light DB
query in order to validate your cache on each request.  Then, each That
would be a significant hit on big changes involving many records.  But
where that's unusual, it might be a big win.  There are a lot of gotchas
with this approach (figuring out the query-table dependencies, etc.), but
it seems possible.

BTW, I thinking server-side caching is the optimal solution here.  I
previously lobbied -hackers for implementing a server-side result-set
cache in which entire query result sets could be cached (up to a
configurable limit) and returned immediately when none of the underlying
tables had changed
(http://www.deja.com/viewthread.xp?AN=602084610&search=thread).  I still
think that would be a huge performance win in the vast majority of
systems (including mine), but it is not supposedly not trivial.  The idea
won absolutely no fans among the developers/hackers.  There was some talk
about caching the query plans, but I think that ultimately got dismissed
as well.  I wish I had time to work on this one.

Regards,
Ed Loehr


RE: Re: how to know when a table is altered

От
"Vincenzo Passoli"
Дата:
hello Ed Loehr,

1.your solution (table-based caching) is very close to my actual thinking.

2.Another problem is the 'alter table' command.

3.SQL does't have a TRIGGER on this 'event'  (CREATE TRIGGER mytrig ON 
mytable FOR ALTER AS ...). Can be Added ?

4.May be beautiful if the db tells to the app when a trigger is fired, so 
the app can update thing without go crazy with asking that to the db every 
time. Is there a solution?

5.For the query table dependencies (a proposal, i've not used this 
solution!):

$sql= "select a.f1,a.f2,b.f3,c.f4 from t1 as a, t2 as b, t3 as c where  
...."
we can extract the tables used in a query

instead of writing  $sql=as before,  write a thing similar to (supposing 
DBI+perl+mod_perl)

my @array;
my $ptr_array= \@array;

$sql = "select a.f1,a.f2,b.f3,c.f4 from 
".&add_check_table('t1',$ptr_array)." as a,".      &add_check_table('t2',$ptr_array) . " as b, ....


---> &add_check_table=sub to push table to check in the array @array, return 
the name of the table, i.e. t1, t2 ...

then

call &do_check ($ptr_array)
using table_status, the sub do_check return 1 if min(last_changes for every 
table in @array) is older that the caching of this query results, we must 
have the query result somewhere (on ( properly locked) files?) and the last 
time we perfomed the query.

then

if (&do_check($ptr_array)){  fetch rows  store in cache
}
-->use the cache

Probably this solution must be used when is logical to be used.

bye,
valter



>From: Ed Loehr <eloehr@austin.rr.com>
>To: Vincenzo Passoli <maweb@hotmail.com>, pgsql-sql@postgresql.org
>Subject: Re: [SQL] how to know when a table is altered
>Date: Wed, 07 Jun 2000 11:49:55 -0500
>
>Ed Loehr wrote:
> >
> > Vincenzo Passoli wrote:
> > >
> > > i'm developing a framework (mod_perl+apache) that reads the db-schema 
>and
> > > explode html forms.
> > >
> > > now i read the schema and cache it into perl-hashes to speedup things.
> > >
> > > my problem is to recognise when a table is altered so that the 
>framework can
> > > update the related forms connected to the db tables.
> > > i don't want to read the schema every time.
> > >
> > > How can i implement this ?
> >
> > My sub-optimal approach was to cache all of the generally static tables
> > (requiring a restart to reload them if they changed), and query the
> > rest.  You can avoid a lot of joins by querying the db for the foreign
> > keys to static tables and then looking them up only in the app cache.
> > But caching query results and invalidating them when the underlying
> > tables changed would greatly simplify my app and speed things up, so I'd
> > love to hear if others have a better/faster solution here.
>
>I was thinking about another possible approach (and definitely
>half-baked).  I'd call it "table-based caching".  Suppose you created a
>table specifically for tracking how recently a table had been updated,
>e.g.,
>
>    create table table_status (
>        tablename    varchar not null unique,
>        last_change    timestamp not null
>    );
>
>Then create triggers for every table that updated
>table_status.last_change = now() on every UPDATE/DELETE/INSERT.  Then, to
>determine when you need to invalidate the application cache, you'd load
>this table at the beginning of the request and invalidate cache entries
>involving tables with table_status.last_change more recent than when the
>query results were cached.
>
>If, like most DBs yours is mostly reads, you'd suffer one pretty light DB
>query in order to validate your cache on each request.  Then, each That
>would be a significant hit on big changes involving many records.  But
>where that's unusual, it might be a big win.  There are a lot of gotchas
>with this approach (figuring out the query-table dependencies, etc.), but
>it seems possible.
>
>BTW, I thinking server-side caching is the optimal solution here.  I
>previously lobbied -hackers for implementing a server-side result-set
>cache in which entire query result sets could be cached (up to a
>configurable limit) and returned immediately when none of the underlying
>tables had changed
>(http://www.deja.com/viewthread.xp?AN=602084610&search=thread).  I still
>think that would be a huge performance win in the vast majority of
>systems (including mine), but it is not supposedly not trivial.  The idea
>won absolutely no fans among the developers/hackers.  There was some talk
>about caching the query plans, but I think that ultimately got dismissed
>as well.  I wish I had time to work on this one.
>
>Regards,
>Ed Loehr

________________________________________________________________________
Get Your Private, Free E-mail from MSN Hotmail at http://www.hotmail.com



Re: how to know when a table is altered

От
Ed Loehr
Дата:
Vincenzo Passoli wrote:
> 
> 3.SQL does't have a TRIGGER on this 'event'  (CREATE TRIGGER mytrig ON
> mytable FOR ALTER AS ...). Can be Added ?

I don't know.  Maybe someone else does (though I think pgsql-sql is very
low volume...pgsql-general would get a lot more readers).

> 4.May be beautiful if the db tells to the app when a trigger is fired, so
> the app can update thing without go crazy with asking that to the db every
> time. Is there a solution?

Maybe.  Check out NOTIFY (and LISTEN) at
http://www.postgresql.org/docs/postgres/sql-listen.htmhttp://www.postgresql.org/docs/postgres/sql-notify.htm

I haven't tried it, not sure it fits into DBI's API or model.  I'd like
to hear if you use it with success (or anyone else who is already using
it successfully within modperl/DBI).

If it turns out that DBI can't handle LISTEN/NOTIFY, it might be possible
to do it through a 3rd app that somehow listens and signals the modperl
servers (yuck).


> 5.For the query table dependencies (a proposal, i've not used this
> solution!):
> 
> $sql= "select a.f1,a.f2,b.f3,c.f4 from t1 as a, t2 as b, t3 as c where
> ...."
> we can extract the tables used in a query
> 
> instead of writing  $sql=as before,  write a thing similar to (supposing
> DBI+perl+mod_perl)
> 
> my @array;
> my $ptr_array= \@array;
> 
> $sql = "select a.f1,a.f2,b.f3,c.f4 from
> ".&add_check_table('t1',$ptr_array)." as a,".
>        &add_check_table('t2',$ptr_array) . " as b, ....
> 
> ---> &add_check_table=sub to push table to check in the array @array, return
> the name of the table, i.e. t1, t2 ...
> 
> then
> 
> call &do_check ($ptr_array)
> using table_status, the sub do_check return 1 if min(last_changes for every
> table in @array) is older that the caching of this query results, we must
> have the query result somewhere (on ( properly locked) files?) and the last
> time we perfomed the query.
> 
> then
> 
> if (&do_check($ptr_array)){
>    fetch rows
>    store in cache
> }
> -->use the cache


I haven't seen that syntax before with your use of "as", but I get your
gist.  Sounds reasonable, though it looks like a major pain, stealing
most of the pleasure and convenience of SQL.  I'd almost be tempted to
build a regex'er to pick out the table names from each query in a layer
between DBI and the app until the regex performance became an issue.

Regards,
Ed Loehr