通过触发器实现物化视图_MySQL
bitsCN.com
通过触发器实现物化视图 在电商平台中,我们有时需要对用户订单进行一些聚合计算,如订单总数有多少,总金额有多少,平均价格是多少,而实现这个特性基本有下面几个办法: 一, 每次查询这些聚合信息的时候,直接执行SQL语句的sum,avg,count等,好处是实现简单,不足是每次均需要进行扫表查询,特别是订单变更比较少,而查询比较多的情况下,此方法会浪费不少的机器资源。 二, 新建一个聚合表,当有订单增删改的时候,通过程序进行计算新的聚合信息,然后存储到该聚合表,每次查询的时候只需查询对应计算好的记录即可,好处是查询非常简单,不足是需要应用程序进行同步聚合信息,且如果订单库操作整个,而聚合库失败,则需要保证数据的一致性。 三,利用DB的触发器实现物化视图的方式,好处是数据的同步交给db 去保证,应用程序无需关注,并且若触发器执行失败,则对应的源表操作也会回滚,不足是需要开发对应的触发器程序。本文主要说明用触发器实现这样的一个特性,为了更好的说明如何创建的过程,我们举了这样一个例子,该例子已经在mysql全部调试通过。 1, 新建一个订单表 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,创建一个存储聚合信息的表 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) //因为需要按照产品名字聚合,这里把product_name作为唯一key进行去重 ) engine=innodb; 3,为表orders创建after insert的触发器 首先说明一下如何查看一个表中是否已经创建了哪些触发器:
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,为表orders创建after update的触发器 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), //错误,此时的price_sum已经是新值, 不能重新 -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), //错误,此时的price_sum已经是新值, 不能重新 -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,为表orders创建after delete的触发器 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 ; 作者 tenfyguo bitsCN.com

热AI工具

Undresser.AI Undress
人工智能驱动的应用程序,用于创建逼真的裸体照片

AI Clothes Remover
用于从照片中去除衣服的在线人工智能工具。

Undress AI Tool
免费脱衣服图片

Clothoff.io
AI脱衣机

AI Hentai Generator
免费生成ai无尽的。

热门文章

热工具

记事本++7.3.1
好用且免费的代码编辑器

SublimeText3汉化版
中文版,非常好用

禅工作室 13.0.1
功能强大的PHP集成开发环境

Dreamweaver CS6
视觉化网页开发工具

SublimeText3 Mac版
神级代码编辑软件(SublimeText3)

随着社交媒体的迅速发展,小红书已经成为了备受青睐的社交平台之一。用户可以通过创建小红书号来展示个人身份,并与其他用户交流互动。如果你需要查找某个用户的小红书号码,可以按照以下简单步骤进行操作。一、如何用小红书号查找用户?1.打开小红书APP,点击右下角的“发现”按钮,然后选择“笔记”选项。2.在笔记列表中,找到你想查找的用户发布的那篇笔记。点击进入笔记详情页。3.在笔记详情页中,点击用户头像下方的“关注”按钮,即可进入该用户的个人主页。4.在用户个人主页右上角,点击三个点按钮,然后选择“个人信息

“本地用户和组”实用程序内置于“计算机管理”中,可以从控制台访问,也可以独立访问。但是,一些用户发现Windows11中缺少本地用户和组。对于可以访问它的一些人来说,该消息显示,此管理单元可能不适用于此版本的Windows10。若要管理此计算机的用户帐户,请使用“控制面板”中的“用户帐户”工具。该问题已在上一次迭代Windows10中报告,并且通常是由于用户端的问题或疏忽引起的。为什么Windows11中缺少本地用户和组?您运行的是Windows家庭版,本地用户和组在专业版及更高版本上可用。活动

在Ubuntu系统中,root用户通常是禁用状态的。要激活root用户,可以使用passwd命令设置密码,然后使用su-命令以root身份登录。根用户是具有系统管理权限且不受限制的用户。他拥有访问和修改文件、用户管理、软件安装和删除,以及系统配置更改等权限。根用户与普通用户有着明显的区别,根用户拥有系统中最高的权限和更广泛的控制权。根用户可以执行重要的系统命令和编辑系统文件,而普通用户则无法做到这一点。在本指南中,我将探讨Ubuntu根用户,如何以根用户身份登录,以及它与普通用户的不同之处。注意

由于权限,并不总是可以访问某些文件夹,在今天的指南中,我们将向您展示如何在Windows11上的旧硬盘驱动器上访问用户文件夹。此过程很简单,但可能需要一段时间,有时甚至数小时,具体取决于驱动器的大小,因此请格外耐心并严格按照本指南中的说明进行操作。为什么我无法访问旧硬盘上的用户文件夹?用户文件夹的所有权属于另一台电脑,因此您无法对其进行修改。除了所有权之外,您对该文件夹没有任何权限。如何打开旧硬盘上的用户文件?1.取得文件夹的所有权并更改权限找到旧的用户目录,右键单击它,然后选择属性。导航到“安

Ubuntu系统添加了很多用户,想在不用的用户想要删除,该怎么删除呢?下面我们就来看看详细的教程。1、打开终端命令行,运用userdel命令删除指定的用户,注意要加sudo权限指令,如下图所示2、在删除的时候一定注意是在管理员目录下的,普通的用户是没有这个权限的,如下图所示3、删除指令执行完了以后怎么判断是否真正删除了呢?下面我们运用cat命令打开passwd文件,如下图所示4、我们看到passwd文件中已经没有了所删除的用户信息了,这证明用户已经被删除了,如下图所示5、然后我们进入home文件

sudo(超级用户执行)是Linux和Unix系统中的一个关键命令,允许普通用户以root权限运行特定命令。sudo的功能主要体现在以下几个方面:提供权限控制:sudo通过授权用户以临时方式获取超级用户权限,从而实现了对系统资源和敏感操作的严格控制。普通用户只能在需要时通过sudo获得临时的特权,而不需要一直以超级用户身份登录。提升安全性:通过使用sudo,可以避免在常规操作中使用root账户。使用root账户进行所有操作可能会导致意外的系统损坏,因为任何错误或不小心的操作都将具有完全的权限。而

Microsoft开始推出作为Windows503145511H22或更高版本的可选更新向公众KB2。这是第一个默认启用Windows11Moment4功能的更新,包括受支持区域中的WindowsCopilot、对“开始”菜单中项目的预览支持、任务栏的取消分组等。此外,它还修复了Windows11的几个错误,包括导致内存泄漏的潜在性能问题。但具有讽刺意味的是,2023年<>月的可选更新对于尝试安装更新的用户甚至已经安装更新的用户来说都是一场灾难。许多用户不会安装此Wi

Linux系统中的用户密码存储机制解析在Linux系统中,用户密码的存储是非常重要的安全机制之一。本文将解析Linux系统中用户密码的存储机制,包括密码的加密存储、密码的验证过程以及如何安全地管理用户密码。同时,将通过具体的代码示例展示密码存储的实际操作过程。一、密码的加密存储在Linux系统中,用户密码并不是以明文的形式存储在系统中,而是经过加密后保存。L
