MySQL的视图、物化视图、触发器、存储过程理解
- 一、视图:(相当于一个路径访问,简化sql语句,执行一些经常要输出的sql语句)
- 优点:
- 缺点:
- 视图再什么时候不能进行新增或则修改:
- 语法:
- 二、触发器:(类似框架中的事件,监听某一个动作的时候被触发,希望同步更新数据,数据同步,比如修改员工信息表,也要同时修改员工扩展表)
- 三、存储过程:(类似与PHP中的方法,可以传递参数,也可以不传递参数、实现中必须先编译存储过程、再调用、存储过程中可以返回多个结果集,类似看成PHP的单例模式,不想多次链接数据库,效率会比较高,不耗资源)
- 四、物化视图(其实物化视图就是一张实体的表,可用来统计后的数据存储到这张视图表中)
一、视图:(相当于一个路径访问,简化sql语句,执行一些经常要输出的sql语句)
优点:
1. 简化了SQL的语句
2. 安全性(不暴漏一些重要的字段)
3. 对于数据表进行重构(例如:希望把两个表进行合并,这样会导致用户目前无法访问到这两个表的数据,所以先进行一个视图创建,把数据存储到虚拟视图表中,用户直接访问视图,随后直接合并两个表,因为合并中不会影响到视图中的数据)
缺点:
1. 性能会很差:从表视图查询数据可能会很慢
2. 表依赖性会很差:从每个新建的表都要新建一个视图,其中有一个表修改了数据,两个都得同时修改
视图再什么时候不能进行新增或则修改:
1. 有聚合函数的时候
2. 包含子查询
3. 存在join的时候
语法:
create view 【视图名称 】 as
sql的语法(select * from table_name);
例子:create view user as select user_id,user_name from swoole_user;
-- 查询视图数据语法:
select * from 【视图名称 】
例子:select * from user;
-- 删除一个视图 drop view 【 视图名称 】
例子:drop view user;
二、触发器:(类似框架中的事件,监听某一个动作的时候被触发,希望同步更新数据,数据同步,比如修改员工信息表,也要同时修改员工扩展表)
语法:
create trigger 【 触发器名称 】 【触发器执行的事件 】 【 触发的执行动作 】
on 【 表 】
for each row
begin
-- 业务逻辑代码,比如更新操作
end;
-- 删除触发器:
drop trigger 【触发器名称】
-- 触发器执行的事件
1. before:执行前的事件
2. after:执行后的事件
-- 触发的执行动作
1.CURL:数据库的基本操作
举个栗子:
-- 代码解释:创建一个user_login 触发器再执行user表操作之前触发insert事件,把数据添加到user_login_info 表中(这样可以实时更新数据同步)
create trigger user_login before insert
on user
for each row
begin
insert into user_login_info (name) values('张三');
end;
三、存储过程:(类似与PHP中的方法,可以传递参数,也可以不传递参数、实现中必须先编译存储过程、再调用、存储过程中可以返回多个结果集,类似看成PHP的单例模式,不想多次链接数据库,效率会比较高,不耗资源)
应用场景:
1. 一般使用再统计计算
2. erp
3. 一般不适用再电商系统
存储过程的参数类型:
1. in:可以传入参数
2. out:可以输出数据
3. inout:既可以传入参数也可以输出数据
常见的数据类型:
1、数值类型:int、float、double、decimal
2、时间类型:timestamp、date、datetime
3、字符类型:char、varchar、text
第一:创建一个无参的存储过程(方法):
create procedure 【 存储过程名称 】(参数类型 参数名称 参数数据类型)
begin
-- 业务逻辑代码 select * from table_name;
end;
-- 调用存储过程
call 【存储过程名称】(传递的参数)
-- 删除存储过程
drop procedure 【存储过程名称】
-- 举个栗子(结合上面的视图更新信息):
create procedure user_procedure ()
begin
insert into user_login_info(添加到用户登陆信息表) select * from user(视图) ;
end;
-- 调用
call user_procedure();
第二:创建一个有参的存储过程:
create procedure 【存储过程名称】 (参数类型 参数名称 参数数据类型)
begin
// 业务逻辑代码 代码解释:把可以返回的参数数据赋值给某一个字段并返回
select 字段 into 可返回的参数名称 from table_name;
end;
-- 调用存储过程(前提创建的存储过程先进行编译)
call 【存储过程名称】 (传参,@传参)
-- 查询返回结果集
select @返回的参数名称
-- 举个栗子
create procedure user_procedure (in id int, out ret varchar(20))
begin
-- 代码解释:select 查询出来的字段值赋值给ret参数,where id = 传过来的参数id
select user_name into ret from user_info where id = id;
end;
-- 调用:call(2,@ret);
-- 查询结果集:select @返回的结果集名称 @ret
第三、带有判断条件并且有参数的存储过程:
create procedure user_procedure (in id int, out ret varchar(20))
begin
if id > 1 then
set ret = '我是用户一号';
elseif id > 2 then
set ret = '我是用户二号';
end if;
-- 执行存储过程
call user_procedure(2, @ret);
-- 输出结果集
select @ret;
四、物化视图(其实物化视图就是一张实体的表,可用来统计后的数据存储到这张视图表中)
- 例如:实际工作中,有些需求需要统计大量的数据,用到聚合函数进行计算,
- 如果数据量大的话,执行时间消耗太多,可以使用物化视图新建一张表来存储统计数量
- 把查询统计出来后的数据添加到物化视图中
根据项目需求;
第一、定时更新(开销小,误差大)使用到存储过程、定时调用call()更新:
1、首先先创建一个物化视图表,作为统计后的数据存储(这里就省略创建表的操作,表明定义为 user_view_info).....
2、接入查询原有的最新数据、再添加到物化视图表中
-- 创建一个视图(其实就是一个中间表,简化了SQL语句而已)
create view user_view as
create view por_view as
select
supply_name,
count(*) pro_count,
sum(pro_price) pro_price_sum,
avg(pro_price) pro_price_avg,
sum(pro_num) pro_num_sum,
avg(pro_num) pro_num_avg
from
purchase_order
group by
supply_name;
-- 接着创建一个存储过程操作
create procedure user_procedure ()
begin
-- 首先删除原有的物化视图表
truncate table purchase_mv (物化视图名称)
insert into user_view_info(物化视图表)select * from user_view(视图表)
end;
-- call user_procedure(); shell脚本定时更新调用
第二、实时更新数据(开销大,误差小或则基本没有误差)
* 使用触发器操作,首先要定义变量,来存储查询出来后的数据结果,然而再把这些
-- 新建一个触发器
create tirgger purcharse_mv_trigger_ins (视图名称)
after insert(触发后执行) (执行动作insert)
on purchase_order (执行这个订单表后,会触发一下操作)
for each row
begin
# 先初始化变量
set @old_pro_price_sum = 0;
set @old_pro_price_avg = 0;
set @old_pro_num_sum = 0;
set @old_pro_num_avg = 0;
set @old_pro_count = 0;
# 查询出之前的信息然后记录到不同的变量中(也就是上面初始化变量中)
select
# 字段值不为空的时候
IFNULL(pro_price_sum,0),IFNULL(pro_price_avg,0),
IFNULL(pro_num_sum,0),IFNULL(pro_num_avg,0),
IFNULL(pro_count,0)
from
purchase_mv(物化视图表)
where
supply_name = new.supply_name
into
# 赋值到变量中
@old_pro_price_sum,@old_pro_price_avg,@old_pro_num_sum,@old_pro_num_avg,@old_pro_count;
# 然后再计算统计新的数据赋值到新的变量中(实时更新)
SET @new_pro_count = @old_pro_count + 1;
SET @new_pro_price_sum = @old_pro_price_sum + NEW.pro_price;
SET @new_pro_price_avg = @new_pro_price_sum / @new_pro_count;
SET @new_pro_num_sum = @old_pro_num_sum + NEW.pro_num;
SET @new_pro_num_avg = @new_pro_num_sum / @new_pro_count;
# 更新到物化视图表中
replace insert into
purchase_mv (物化视图表)
values(
NEW.supply_name, @new_pro_count,
@new_pro_price_sum, IFNULL(@new_pro_price_avg, 0),
@new_pro_num_sum, IFNULL(@new_pro_num_avg, 0)
);
end;
-- 如果有侵权请联系删除。