mysql触发器实现oracle物化视图示例代码

 更新时间:2014年02月08日 15:27:01   作者:  
mysql触发器实现oracle物化视图即不是基于基表的虚表,而是根据表实际存在的实表,需要的朋友可以参考下

oracle数据库支持物化视图--不是基于基表的虚表,而是根据表实际存在的实表,即物化视图的数据存储在非易失的存储设备上。
下面实验创建ON COMMIT 的FAST刷新模式,在mysql中用触发器实现insert , update , delete 刷新操作
1、基础表创建,Orders 表为基表,Order_mv为物化视图表

复制代码 代码如下:

mysql> create table Orders(
-> order_id int not null auto_increment,
-> product_name varchar(30)not null,
-> price decimal(10,0) not null ,
-> amount smallint not null ,
-> primary key (order_id));
Query OK, 0 rows affected
mysql> create table Order_mv(
-> product_name varchar(30) not null,
-> price_sum decimal(8.2) not null,
-> amount_sum int not null,
-> price_avg float not null,
-> order_cnt int not null,
-> unique index(product_name));
Query OK, 0 rows affected

2、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(order_cnt,0)
from Order_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 Order_mv
values(new.product_name,@new_price_sum,@new_amount_sum,@new_price_avg,@new_orders_cnt);
end;
$$
delimiter ;

3、update触发器
复制代码 代码如下:

delimiter $$
create trigger tgr_Orders_update
before update 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;

set @cur_price=0;
set @cur_amount=0;

select price,amount from Orders where order_id=new.order_id
into @cur_price,@cur_amount;

select ifnull(price_sum,0),ifnull(amount_sum,0),ifnull(price_avg,0),ifnull(order_cnt,0)
from Order_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-@cur_price+new.price;
set @new_amount_sum=@old_amount_sum-@cur_amount+new.amount;
set @new_orders_cnt=@old_orders_cnt;
set @new_price_avg=@new_price_sum/@new_orders_cnt;

replace into Order_mv
values(new.product_name,@new_price_sum,@new_amount_sum,@new_price_avg,@new_orders_cnt);
end;
$$
delimiter ;

4、delete触发器
复制代码 代码如下:

delimiter $$
create trigger tgr_Orders_delete
after delete 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;

set @cur_price=0;
set @cur_amount=0;

select price,amount from Orders where order_id=old.order_id
into @cur_price,@cur_amount;

select ifnull(price_sum,0),ifnull(amount_sum,0),ifnull(price_avg,0),ifnull(order_cnt,0)
from Order_mv
where product_name=old.product_name
into @old_price_sum,@old_amount_sum,@old_price_avg,@old_orders_cnt;

set @new_price_sum=@old_price_sum - old.price;
set @new_amount_sum=@old_amount_sum - old.amount;
set @new_orders_cnt=@old_orders_cnt - 1;

if @new_orders_cnt>0 then
set @new_price_avg=@new_price_sum/@new_orders_cnt;
replace into Order_mv
values(old.product_name,@new_price_sum,@new_amount_sum,@new_price_avg,@new_orders_cnt);
else
delete from Order_mv where product_name=@old.name;
end if;
end;
$$
delimiter ;

5、这里delete触发器有一个bug,就是在一种产品的最后一个订单被删除的时候,Order_mv表的更新不能实现,不知道这算不算是mysql的一个bug。当然,如果这个也可以直接用sql语句生成数据,而导致的直接后果就是执行效率低。
复制代码 代码如下:

-> insert into Order_mv
-> select product_name ,sum(price),sum(amount),avg(price),count(*) from Orders
-> group by product_name;

相关文章

  • MySQL binlog日志清理的方案分享

    MySQL binlog日志清理的方案分享

    Binlog日志非常重要,但是占用的磁盘空间也很大,我们也需要定期的去清理二进制日志,在MySQL数据库中,提供了自动清理Binlog日志的参数,本文给大家详细介绍了MySQL binlog日志清理方案,需要的朋友可以参考下
    2024-01-01
  • Mysql排序的特性详情

    Mysql排序的特性详情

    这篇文章主要介绍Mysql排序的特性,新写了一个功能,自测和测试环境测试都没问题,但在生产环境会出现偶发问题。于是,加班到12点一直排查问题,终于定位了的问题原因:Mysql Limit查询优化导致。现抽象出问题模型及解决方案,分析给大家,避免大家踩坑,需要的朋友可以参考一下
    2021-10-10
  • mysql tmp_table_size优化之设置多大合适

    mysql tmp_table_size优化之设置多大合适

    这篇文章主要介绍了mysql tmp_table_size优化问题,很多朋友都会问tmp_table_size设置多大合适,其实既然你都搜索到这篇文章了,一般大于64M比较好,当然你也可以可以根据自己的机器内容配置增加,一般64位的系统能充分利用大内存
    2016-05-05
  • mysql 8.0.28安装配置方法图文教程(压缩包方式)

    mysql 8.0.28安装配置方法图文教程(压缩包方式)

    这篇文章主要为大家详细介绍了mysql 8.0.28安装配置方法图文教程,文中安装步骤介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2022-06-06
  • 一文带你彻底了解MySQL事务机制

    一文带你彻底了解MySQL事务机制

    一个事情由n个单元组成,这n个单元在执行过程中,要么同时成功,要么同时失败,这就把n个单元放在了一个事务之中,这篇文章主要给大家详细介绍MySQL的事务机制,感兴趣的同学欢迎阅读本文
    2023-06-06
  • Mysql系列SQL查询语句书写顺序及执行顺序详解

    Mysql系列SQL查询语句书写顺序及执行顺序详解

    这篇文章主要为大家介绍了Mysql系列SQL查询语句的书写顺序及执行顺序示例详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步
    2021-10-10
  • MySQL查询进阶操作从函数到表连接的使用

    MySQL查询进阶操作从函数到表连接的使用

    这篇文章主要介绍了MySQL查询进阶从函数到表连接的使用,包括mysql函数的使用,MySQL的分组分页及查询关键字的执行顺序,本文通过实例代码给大家介绍的非常详细,需要的朋友可以参考下
    2022-08-08
  • 浅析mysql union和union all

    浅析mysql union和union all

    union 是对数据进行并集操作,不包括重复行,同时进行默认排序而Union all 是对数据进行并集操作,包括重复行,不进行排序,下面给大家详细介绍mysql union和union all,感兴趣的朋友一起看看吧
    2017-10-10
  • Win中安装mysql的详细步骤

    Win中安装mysql的详细步骤

    这篇文章主要为大家详细介绍了Win中安装mysql的详细步骤,文中安装步骤介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2019-10-10
  • 教你使用VS Code的MySQL扩展管理数据库的方法

    教你使用VS Code的MySQL扩展管理数据库的方法

    这篇文章主要介绍了使用VS Code的MySQL扩展管理数据库,在本文告诉你如何用VS Code的扩展程序管理MySQL数据库,包括连接到MySQL、新建数据库和表、修改字段定义、简单的查询方法以及导入导出,需要的朋友可以参考下
    2022-01-01

最新评论