Re: Database design and triggers... - Mailing list pgsql-general

From romantercero@gmail.com
Subject Re: Database design and triggers...
Date
Msg-id 1157737438.745213.189990@h48g2000cwc.googlegroups.com
Whole thread Raw
In response to Re: Database design and triggers...  (romantercero@gmail.com)
Responses Re: Database design and triggers...
List pgsql-general
Hi Brandon,

Thank you for your response.

Yes, I see what you mean when you say that I can list Qty in signed
integers and use a view. Good point.

But I'm not sure as to using a view vs using a permanent table updated
by triggers. It seems we are dealing with the clasic tradeoff between
speed & storage space.

A permanent table would duplicate data and even though it would toll
write operations I suspect it would be faster than users bringing up a
view every time they wish to execute a transaction.

Any Sugestions as to which way I should go on the tradeoff and why?

Thanx!

"Brandon Aiken" wrote:
> Actually, I don't think you need Table 2 at all.  Rather, you can fairly
> easily incorporate all the functionality of CurrentCountTable into Table
> 2 and then use a query or a VIEW.
>
> Say you have these two tables.  [I'm not the best at data modeling yet,
> so I wouldn't necessarily take these verbatim.  I'm still a newbie.
> Listed here is pseudo-SQL.]
>
> TABLE "Transaction"
> (
>   "TransactionID" serial,
>   "OperationID" integer,
>   "OperationType" char(15) NOT NULL,
>   "ClientID" integer NOT NULL,
>   "TransactionDate" date NOT NULL DEFAULT 'epoch',
>   "UserID" char(15) NOT NULL,
>   PRIMARY KEY ("TransactionID"),
>   UNIQUE ("OperationID")
> )
>
> TABLE "TransactionItem"
> (
>   "TransactionItemID" serial,
>   "OperationID" integer NOT NULL,
>   "PartID" integer NOT NULL,
>   "LotID" integer NOT NULL,
>   "Qty" integer NOT NULL,
>   PRIMARY KEY ("TransItemID"),
>   FOREIGN KEY ("OperationID")
>       REFERENCES "Transaction" ("OperationID")
>       ON UPDATE CASCADE ON DELETE RESTRICT,
>   UNIQUE ("OperationID", "PartID")
> )
>
> Now, when you store Qty, you store a positive number if the inventory
> increases and a negative number if it decreases.
>
> Now, you can use a query or create a VIEW based on this query:
>
> SELECT "OperationID"
>    , "ClientID"
>    , "TransactionDate"
>    , "PartID"
>    , "LotID"
>    , "Qty"
>    , "UserID"
> FROM "Transaction" NATURAL JOIN "TransactionItem";
>
> Alternately, you can continue to store the Qty as an unsigned integer
> and then use this query/VIEW:
>
> SELECT "OperationID"
>    , "ClientID"
>    , "TransactionDate"
>    , "PartID"
>    , "LotID"
>    , CASE
>         WHEN "OperationType" = 'Incoming' THEN "Qty"
>         WHEN "OperationType" = 'Outgoing' THEN (-1 * "Qty")
>      END
>    , "UserID"
> FROM "Transaction" NATURAL JOIN "TransactionItem";
>
> As far as speed, speed is always an issue.  PostgreSQL is going to
> perform better than Access, but don't use good performance as a crutch
> for bad design.
>
> As far as normalization, it is possible to take it too far.  There is a
> time when de-normalizing a database will significantly improve its
> performance even if it involves duplicating data.  4NF is not the goal
> of DB design, having a usable database is.  Knowing when and how to
> de-normalize is much more difficult than learning to design a normalized
> data model.
>
>
> --
> Brandon Aiken
> CS/IT Systems Engineer
>
> -----Original Message-----
> From: pgsql-general-owner@postgresql.org
> [mailto:pgsql-general-owner@postgresql.org] On Behalf Of
> romantercero@gmail.com
> Sent: Thursday, September 07, 2006 7:09 PM
> To: pgsql-general@postgresql.org
> Subject: Re: [GENERAL] Database design and triggers...
>
> Hi Brandon, thanks for answering.
>
> The information regarding a transaction is stored on two separate
> tables due to normalization. The first table stores general information
> regarding the transaction like Transaction number, date, customer ID,
> type of transaction, userID etc... The second table stores the details
> of the purchase like the products and quantities that the transaction
> affected. Like this:
>
> Table 1:
> Operation#     Type_of_operation    Client#        Date    UserID
> 1           Inbound                    10        1/1/2000
> Paul37
> 2            Outbound                    10        1/2/2000
> Steve04
>
> Table 2:
> Operation#    Part#   Lot#           Qty
> 1        X    a        10
> 1        Y    ds1        9
> 1        Z    54ad        7
> 2        X    a        10
>
> Table 2 has Table 1's Operation field as a Foreign key.
>
> Now, to obtain a current count of  Part X we have to create a temporary
> table on which we can use aggregate functions.
>
> CurrentCountTable:
>
> Operation    Client#    Date    Part#    Lot#    Qty    UserID
> 1    10    1/1/2000    X    a    +10    Paul37
> 1    10    1/1/2000    Y    ds1    +9    Paul37
> 1    10    1/1/2000    Z    54as    +7    Paul37
> 2    10    1/2/2000    X    a    -10    Steve04
>
> Now, on the temporary table called CurrentCountTable we can use an
> aggregate function, The problem is that creating this table is slow
> with INSERT INTO, and so are aggregate functions (On MS Access). So
> Naturally it occurred to me that triggers can keep a permanent version
> of the CurrentCountTable up to date every time some one inserts in to
> Table 1 and Table 2. But it has to be perfect to avoid inconsistencies.
>
> So, are triggers a safe bet? Is using triggers more advisable over the
> temporary table solution because on PSQL speed is not an issue? Or
> should I use views?
>
> Thanks!!! (Hope the tables got listed correctly :-/ )
>
>
>
> "Brandon Aiken" wrote:
> > It's not clear to me how your data is organized or exactly what you're
> > counting.  If I understand you correctly, yes, you could use triggers
> to
> > maintain a table in this manner.  However, why can't you simply use a
> > SELECT query using the SUM() or COUNT() aggregate functions?  If the
> > queries are slow, do some index tuning.
> >
> > --
> > Brandon Aiken
> > CS/IT Systems Engineer
> >
> > -----Original Message-----
> > From: pgsql-general-owner@postgresql.org
> > [mailto:pgsql-general-owner@postgresql.org] On Behalf Of
> > romantercero@gmail.com
> > Sent: Wednesday, September 06, 2006 2:05 PM
> > To: pgsql-general@postgresql.org
> > Subject: [GENERAL] Database design and triggers...
> >
> > Hi everybody. Hope I'm posting in the correct group.
> >
> > My question is part design and part implementation.
> >
> > Since we are creating an inventory system we need to have the clients
> > pull up current inventory. Also, we need to have the past transactions
> > stored for reference and billing. In our previous system in MS Access
> > we accomplished this by adding up all of the transactions stored in
> two
> > tables and generating a temporary table with the latest inventory
> > count. The problem with this approach is that it is slow because the
> > temporary table has to be created every time a user needs to see a
> > report or work on a form. Even when instead of creating a temporary
> > table we use a query it is still slow. With postgreSQL I found out
> > about triggers and I figure that instead of calculating the current
> > inventory count and storing it in a table every time a client needs it
> > I could have a triggers maintain a table with the current count by
> > incrementing or decreasing the amounts each time a transaction is
> > stored in the transaction tables. My worry is that if for some reason
> a
> > trigger were to somehow fail to execute correctly there would be an
> > inconsistency between the transactions table and the current inventory
> > count table and it would have to be calculated from scratch taking in
> > to account all of the past transactions in the transactions table.
> >
> > Are trigger a very safe way to use in the way I describe? Or should I
> > try using views or stick with the temporary table solution we already
> > have?
> >
> > My second part of the question is if there is a tutorial for triggers
> > and stored procedures and what is the difference between Procedures
> and
> > Functions?
> >
> > Thanks Beforehand!
> >
> >
> > ---------------------------(end of
> broadcast)---------------------------
> > TIP 1: if posting/reading through Usenet, please send an appropriate
> >        subscribe-nomail command to majordomo@postgresql.org so that
> your
> >        message can get through to the mailing list cleanly
> >
> > ---------------------------(end of
> broadcast)---------------------------
> > TIP 5: don't forget to increase your free space map settings
>
>
> ---------------------------(end of broadcast)---------------------------
> TIP 5: don't forget to increase your free space map settings
>
> ---------------------------(end of broadcast)---------------------------
> TIP 4: Have you searched our list archives?
>
>                http://archives.postgresql.org


pgsql-general by date:

Previous
From: Tom Lane
Date:
Subject: Re: execute in pl/pgsql
Next
From: Michelle Konzack
Date:
Subject: Re: plz unsubscribe me