Materialized View through triggers

Source: Internet
Author: User

On the e-commerce platform, we sometimes need to perform some aggregation calculations on user orders, such as the total number of orders, the total amount, and the average price, there are several methods to achieve this feature:

1. Execute the sum, AVG, and count statements of the SQL statement each time you query the aggregated information. The advantage is that the SQL statement is simple, and the result is that you need to scan the table every time, this method wastes a lot of machine resources, especially when there are few changes to orders and there are many queries.

2. Create an aggregate table. When an order is added, deleted, or modified, compute the new aggregate information through the program and store it to the aggregate table, you only need to query the corresponding calculated record for each query. The advantage is that the query is very simple, but the application needs to synchronize the aggregated information. If the order library is complete, but the aggregation library fails, data consistency must be ensured.

3. The database trigger is used to implement the materialized view. The advantage is that data synchronization is provided to the dB to ensure that the application does not need to pay attention to the view. If the trigger fails to be executed, the corresponding source table operations will also be rolled back, and the development of the corresponding trigger program is insufficient. This article mainly describes how to use a trigger to implement such a feature. In order to better illustrate how to create a process, we provide an example that has been successfully debugged in MySQL.

1. Create an order table

Drop table orders if exists;

Create Table orders (

Order_id int unsigned not null auto_increment,

Product_name varchar (30) not null,

Price decimal (8, 2) not null,

Amount smallint not null,

Primary Key (order_id)

) Engine = InnoDB;

2. Create a table that stores aggregate information

Drop table orders_mv if exists;

Create Table orders_mv (

Product_name varchar (30) not null,

Price_sum decimal (8, 2) not null,

Amount_sum int not null,

Price_avg float not null,

Orders_cnt int not null,

Unique key product_name (product_name) // according to the product name aggregation, product_name is used as the unique key for de-duplication.

) Engine = InnoDB;

3. Create an after insert trigger for the table orders

First, explain how to check whether a table has created any triggers:
Select * From information_schema.triggers where event_object_table = 'tbl _ name' \ G

Drop trigger tgr_orders_insert;

Delimiter $
Create trigger tgr_orders_insert
After insert on orders
For each row
Begin
Set @ old_price_sum = 0;
Set @ old_amount_sum = 0;
Set @ old_price_avg = 0;
Set @ old_orders_cnt = 0;

Select ifnull (price_sum, 0), ifnull (amount_sum, 0), ifnull (price_avg, 0), ifnull (orders_cnt, 0)
From orders_mv
Where product_name = new. product_name
Into @ old_price_sum, @ old_amount_sum, @ old_price_avg, @ old_orders_cnt;

Set @ new_price_sum = @ old_price_sum + new. price;
Set @ new_amount_sum = @ old_amount_sum + new. amount;
Set @ new_orders_cnt = @ old_orders_cnt + 1;
Set @ new_price_avg = @ new_price_sum/@ new_orders_cnt;

Replace into orders_mv
Values (New. product_name, @ new_price_sum, @ new_amount_sum, @ new_price_avg, @ new_orders_cnt );

End;
$
Delimiter;

4. Create an After update trigger for the table orders

Drop trigger tgr_orders_update;

Delimiter $
Create trigger tgr_orders_update
After update on orders
For each row
Begin
If (strcmp (old. product_name, new. product_name) then
Update orders_mv
Set
Price_sum = (price_sum-old. Price ),
Amount_sum = (amount_sum-old. amount ),
Orders_cnt = (orders_cnt-1 ),

// Error. At this time, price_sum is a new value and cannot be used again-old. Price + new. Price
// Price_avg = (price_sum-old. Price)/If (orders_cnt-1)> 0, (orders_cnt-1), 1)

Price_avg = price_sum/If (orders_cnt> 0, orders_cnt, 1)

Where product_name = old. product_name;

Set @ old_price_sum = 0;
Set @ old_amount_sum = 0;
Set @ old_price_avg = 0;
Set @ old_orders_cnt = 0;

Select ifnull (price_sum, 0), ifnull (amount_sum, 0), ifnull (price_avg, 0), ifnull (orders_cnt, 0)
From orders_mv
Where product_name = new. product_name
Into @ old_price_sum, @ old_amount_sum, @ old_price_avg, @ old_orders_cnt;

Set @ new_price_sum = @ old_price_sum + new. price;
Set @ new_amount_sum = @ old_amount_sum + new. amount;
Set @ new_orders_cnt = @ old_orders_cnt + 1;
Set @ new_price_avg = @ new_price_sum/@ new_orders_cnt;

Replace into orders_mv
Values (New. product_name, @ new_price_sum, @ new_amount_sum, @ new_price_avg, @ new_orders_cnt );

Else
Update orders_mv
Set
Price_sum = (price_sum-old. Price + new. Price ),
Amount_sum = (amount_sum-old. Amount + new. amount ),

// Error. At this time, price_sum is a new value and cannot be used again-old. Price + new. Price
// Price_avg = (price_sum-old. Price + new. Price)/If (orders_cnt> 0, orders_cnt, 1)

Price_avg = price_sum/If (orders_cnt> 0, orders_cnt, 1)

Where product_name = old. product_name;

End if;
End;
$
Delimiter;

5. Create an After Delete trigger for the table orders

Drop trigger tgr_orders_delete;

Delimiter $
Create trigger tgr_orders_delete
After delete on orders
For each row
Begin
Update orders_mv
Set
Price_sum = (price_sum-old. Price ),
Amount_sum = (amount_sum-old. amount ),
Orders_cnt = (orders_cnt-1 ),
Price_avg = price_sum/If (orders_cnt> 0, orders_cnt, 1)
Where product_name = old. product_name;
End;
$
Delimiter;

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.