MySQL的视图、物化视图、触发器、存储过程理解

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;


-- 如果有侵权请联系删除。

你可能感兴趣的:(MySQL的视图、物化视图、触发器、存储过程理解)