Thread: Storing Snapshot Data

Storing Snapshot Data

From
John Gibson
Date:
Hi, all.

I have a table which is continually updated with the latest totals.  I
would like to take snapshots of some of the data in that table and store
it in a second table to run statistics on it later.  What might some
ways of doing this be?

Illustrative (I hope) example using fruit-qty-on-hand at a grocery store:

Fruit_table   {constantly updated by other processes}

CREATE TABLE "fruit_table" (
    "fruit_name"        varchar(20),
    "fruit_qty"    int4
  );


***TABLE DATA***
fruit name     fruit_qty
apple              5
orange            8
pear                3



monitor_table {stores snapshots of fruit table from time to time}

CREATE TABLE "monitor_table" (
    "monitor_time" timestamp,
    "mon_apples_qty"    int4,
    "mon_oranges_qty"    int4,
    "mon_pears_qty"        int4
);


I got the following to timestamp a single row from the fruit_table and
put the results into the monitor_table:

insert into monitor_table(monitor_time, mon_apples_qty)
select now(), fruit_table.fruit_qty
where fruit_name = 'apple';

Unfortunately, I am stuck on how to get all three into the monitor table
with the same timestamp.  Since the times will be relatively long
between snapshots some type of variables or functions could be used (I
guess) to store the current time ( curr_time := now(); ) and then run
the query three times with first an insert and then two updates using
the variable time stamp on the updates to locate the record to update.

That doesn't sound very elegant to me.  Please help if you have any ideas.

I am definately a newbie, so forgive me if this is trivial.  Also, if
another forum would be better for this, I would appreciate a nudge in
that direction.   :)

...john


Re: Storing Snapshot Data

From
Adrian Klaver
Date:
On Thursday 11 December 2003 12:42 am, John Gibson wrote:
> Hi, all.
>
> I have a table which is continually updated with the latest totals.  I
> would like to take snapshots of some of the data in that table and store
> it in a second table to run statistics on it later.  What might some
> ways of doing this be?
>
> Illustrative (I hope) example using fruit-qty-on-hand at a grocery store:
>
> Fruit_table   {constantly updated by other processes}
>
> CREATE TABLE "fruit_table" (
>     "fruit_name"        varchar(20),
>     "fruit_qty"    int4
>   );
>
>
> ***TABLE DATA***
> fruit name     fruit_qty
> apple              5
> orange            8
> pear                3
>
>
>
> monitor_table {stores snapshots of fruit table from time to time}
>
> CREATE TABLE "monitor_table" (
>     "monitor_time" timestamp,
>     "mon_apples_qty"    int4,
>     "mon_oranges_qty"    int4,
>     "mon_pears_qty"        int4
> );
>
>
> I got the following to timestamp a single row from the fruit_table and
> put the results into the monitor_table:
>
> insert into monitor_table(monitor_time, mon_apples_qty)
> select now(), fruit_table.fruit_qty
> where fruit_name = 'apple';
>
> Unfortunately, I am stuck on how to get all three into the monitor table
> with the same timestamp.  Since the times will be relatively long
> between snapshots some type of variables or functions could be used (I
> guess) to store the current time ( curr_time := now(); ) and then run
> the query three times with first an insert and then two updates using
> the variable time stamp on the updates to locate the record to update.
>
> That doesn't sound very elegant to me.  Please help if you have any ideas.
>
> I am definately a newbie, so forgive me if this is trivial.  Also, if
> another forum would be better for this, I would appreciate a nudge in
> that direction.   :)
>
> ...john
>
>
> ---------------------------(end of broadcast)---------------------------
> TIP 9: the planner will ignore your desire to choose an index scan if your
>       joining column's datatypes do not match

First I would create a monitor table as follows

CREATE TABLE "fruit_table_moinitor" (
     "fruit_name"        varchar(20),
     "fruit_qty"    int4,
     "t_stamp"  timestamp
    );

Then use the following transaction-

BEGIN;

INSERT INTO fruit_table_monitor(fruit_name,fruit_qty,t_stamp) SELECT
fruit_name,fruit_qty,now() from fruit_table;

COMMIT;

Calling the function now() inside a transaction locks the timestamp to the
time at the beginning of the transaction.
--
Adrian Klaver
aklaver@comcast.net

Re: Storing Snapshot Data

From
Tino Wildenhain
Date:
Hi John,

John Gibson schrieb:
> Hi, all.
>
> I have a table which is continually updated with the latest totals.  I
> would like to take snapshots of some of the data in that table and store
> it in a second table to run statistics on it later.  What might some
> ways of doing this be?
>
> Illustrative (I hope) example using fruit-qty-on-hand at a grocery store:
>
> Fruit_table   {constantly updated by other processes}
>
> CREATE TABLE "fruit_table" (
>    "fruit_name"        varchar(20),
>    "fruit_qty"    int4
>  );
>
>
> ***TABLE DATA***
> fruit name     fruit_qty
> apple              5
> orange            8
> pear                3
>
>
>
> monitor_table {stores snapshots of fruit table from time to time}
>
> CREATE TABLE "monitor_table" (
>    "monitor_time" timestamp,
>    "mon_apples_qty"    int4,
>    "mon_oranges_qty"    int4,
>    "mon_pears_qty"        int4
> );
>
>
> I got the following to timestamp a single row from the fruit_table and
> put the results into the monitor_table:
>
> insert into monitor_table(monitor_time, mon_apples_qty)
> select now(), fruit_table.fruit_qty
> where fruit_name = 'apple';
>
> Unfortunately, I am stuck on how to get all three into the monitor table
> with the same timestamp.  Since the times will be relatively long
> between snapshots some type of variables or functions could be used (I
> guess) to store the current time ( curr_time := now(); ) and then run
> the query three times with first an insert and then two updates using
> the variable time stamp on the updates to locate the record to update.

Id use a third table to just store the snapshot times and a sequence
number:

CREATE SEQUENCE monitor_snapshots_id_seq;

CREATE TABLE monitor_snapshots (
    monitor_time timestamp,
    monitor_id int8 DEFAULT nextval('monitor_snapshots_id_seq'::text)
NOT NULL
    );

and then use the following code to take your snapshots:

INSERT INTO monitor_snapshots (monitor_time) VALUES (now());
INSERT INTO monitor_table
     SELECT currval('monitor_snapshots_id_seq'::text) as monitor_id,
            fruit_name,
            fruit_qty
     FROM fruit_table;

Provided you modify your monitor_table
to have monitor_id, fruit_name (perhaps fruit_id is better here),
fruit_qty

If you got a table with fruit_id:fruit_name, you can always retrive
your information via LEFT OUTER JOIN, otherwise you would only get
the kind of fruits available in the given snapshot.

HTH
Tino Wildenhain


Re: Storing Snapshot Data

From
Tom Lane
Date:
John Gibson <gib@edgate.com> writes:
> Unfortunately, I am stuck on how to get all three into the monitor table
> with the same timestamp.

Do all the work in a single SERIALIZABLE transaction.  That gives you a
static, consistent view of the database for as long as you need.

            regards, tom lane