简体   繁体   English

创建触发器以保持最新记录

[英]Create trigger to keep the latest record

I have a Product table which keeps on adding rows with product_id and price .我有一个Product表,它不断添加带有 product_id 和 price 的行。 It has millions of rows.它有数百万行。

It has a product_id as Primary key like below.它有一个product_id作为主键,如下所示。

CREATE TABLE ProductPrice(
product_id VARCHAR2(10),
prod_date DATE ,
price NUMBER(8,0) ,
PRIMARY KEY (product_id)
)

Now this has millions of rows and to get the latest price it get a lot of time.现在这有数百万行,并且要获得最新的价格需要很多时间。

So to manage the latest price, I have created another table which will keep only the latest price with same format.因此,为了管理最新价格,我创建了另一个表格,该表格仅保留具有相同格式的最新价格。

CREATE TABLE ProductPriceLatest(
product_id VARCHAR2(10),
prod_date DATE ,
price NUMBER(8,0) ,
PRIMARY KEY (product_id)
)

And on every insert on original table, i will write a trigger which will update the row in this table.在原始表上的每次插入时,我将编写一个触发器来更新该表中的行。

But how can i get the newly inserted values inside the trigger body?但是如何在触发器主体中获取新插入的值?

I have tried something like this:我试过这样的事情:

CREATE OR REPLACE TRIGGER TRIG_HISTory
AFTER INSERT
  on ProductPriceLatest
  FOR EACH ROW 

DECLARE

BEGIN

UPDATE latest_price
SET price = NEW.price , 
WHERE product_id = NEW.product_id ;        

END;

Thanks in advance.提前致谢。

You need to use the :new keyword to differentiate with :old values.您需要使用:new关键字来区分:old值。 Also, better use AFTER trigger:此外,更好地使用AFTER触发器:

CREATE OR REPLACE TRIGGER TRIG_HISTORY 
AFTER INSERT ON source_table_name
    FOR EACH ROW
DECLARE

BEGIN
MERGE INTO dest_table_name d
    USING (select :new.price p, :new.product_id p_id from dual) s
    ON (d.product_id = s.p_id)
  WHEN MATCHED THEN
    UPDATE SET d.price = s.p
  WHEN NOT MATCHED THEN
    INSERT (price, product_id)
    VALUES (s.p, s.p_id);
END;

Retrieving the latest price from your first table should be fast if you have the correct index.如果您有正确的索引,从您的第一个表中检索最新价格应该很快。 Building the correct index on your ProductPrice table is a far better solution to your problem than trying to maintain a separate table.在您的 ProductPrice 表上建立正确的索引比试图维护一个单独的表更好地解决您的问题。

Your query to get the latest prices would look like this.您获取最新价格的查询将如下所示。

SELECT p.product_id, p.prod_date, p.price
  FROM ProductPrice p
  JOIN (
           SELECT product_id, MAX(prod_date) latest_prod_date
             FROM ProductPrice
            GROUP BY product_id 
       ) m  ON p.product_id = m.product_id 
           AND p.prod_date = m.latest_prod_date
 WHERE p.product_id = ????

This works because the subquery looks up the latest product date for each product.这是有效的,因为子查询会查找每个产品的最新产品日期。 It then uses that information to find the right row in the table to show you.然后它使用该信息在表中查找正确的行以显示给您。

If you create a compound index on (product_id, prod_date, price) this query will run almost miraculously fast.如果你在(product_id, prod_date, price)上创建一个复合索引(product_id, prod_date, price)这个查询的运行速度几乎是奇迹般的快。 That's because the query planner can find the correct index item in O(log n) time or better.那是因为查询计划器可以在 O(log n) 时间或更短的时间内找到正确的索引项。

You can make it into a view like this:你可以把它变成这样的视图:

CREATE OR REPLACE VIEW ProductPriceLatest AS
SELECT p.product_id, p.prod_date, p.price
  FROM ProductPrice p
  JOIN (
           SELECT product_id, MAX(prod_date) latest_prod_date
             FROM ProductPrice
            GROUP BY product_id 
       ) m  ON p.product_id = m.product_id 
           AND p.prod_date = m.latest_prod_date;

Then you can use the view like this:然后你可以像这样使用视图:

SELECT * FROM ProductPriceLatest WHERE product_id = ???

and get the same high performance.并获得相同的高性能。

This is easier, less error-prone, and just as fast as creating a separate table and maintaining it.这更容易,更不容易出错,并且与创建单独的表并维护它一样快。 By the way, DBMS jargon for the table you propose to create is materialized view.顺便说一下,您建议创建的表的 DBMS 术语是物化视图。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM