Search Postgresql Archives

Re: SQL Rule

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Bert wrote:

Hi list

I have a table construction like the one seen below, when i am updating
or inserting i get a recurion, logical. But how to manage it that the
rule is just doing it one time. Or is it possible to do the sum of a
and b in an other way?
Bert, i do this with triggers.  There are pros and cons.

One pro is that you can guarantee the correct result with code that looks like this (I'm coding from memory, there may be some syntax errors):

if new.column_c <> old.column_c then
raise error 'Cannot make direct assignment to calculated column *column_c*';
end if;

Then you follow that up with the assignment, so that the code looks like:

if new.column_c <> old.column_c then
raise error 'Cannot make direct assignment to calculated column *column_c*';
end if;
new.column_c = new.column_a + new.column_b

The con is that these triggers go row-by-row. Shockingly I have found the degradation to be only 100% (instead of 700% or 1000%), so that updates take twice as long. In small-transaction situations this is not a problem, it is lost in the overhead of the transaction itself. On large assigment statements that would take 2 minutes you now have to wait 4 minutes, or break up the assignment.

The really cool thing about it is that you can provide automation built on top of normalized tables. You get this by doing two things:

1) Derived values depend only upon normalized values or other derived values
2) never allow user writes to automated columns, raise an error when that happens

Using views is fine for simple cases, but, and I know this because I've done it, if you expect to automate calculations across 100's of tables including complex and compound calculations, your views will become utterly unworkable, or destroy performance when 28 tables have to be joined together when sombody issues "SELECT Total_exposure FROM Customers"

To really get the benefit, you can provide for a FETCH from parents to children, and also SUMs from children to parent. With that and the simple extension of your example you can have really powerful normalized and automated databases.

CREATE TABLE test
(
 a int2,
 b int2,
 c int2,
 id int2 NOT NULL,
 CONSTRAINT id_test PRIMARY KEY (id)
)
WITHOUT OIDS;
ALTER TABLE test OWNER TO postgres;


CREATE OR REPLACE RULE sum_op AS
   ON INSERT TO test DO  UPDATE test SET c = new.a + new.b
 WHERE test.id = new.id;

CREATE OR REPLACE RULE sum_op_up AS
   ON UPDATE TO test DO  UPDATE test SET c = test.a + test.b
 WHERE test.id = new.id;


---------------------------(end of broadcast)---------------------------
TIP 6: explain analyze is your friend

begin:vcard
fn:Kenneth  Downs
n:Downs;Kenneth 
email;internet:ken@xxxxxxxxxx
tel;work:631-689-7200
tel;fax:631-689-0527
tel;cell:631-379-0010
x-mozilla-html:FALSE
version:2.1
end:vcard


[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Index of Archives]     [Postgresql Jobs]     [Postgresql Admin]     [Postgresql Performance]     [Linux Clusters]     [PHP Home]     [PHP on Windows]     [Kernel Newbies]     [PHP Classes]     [PHP Books]     [PHP Databases]     [Postgresql & PHP]     [Yosemite]
  Powered by Linux