MySQL基础篇(04):存储过程和视图,用法和特性详解
本文源码:github·点这里 || gitee·点这里
一、存储过程
1、概念简介
存储程序是被存储在服务器中的组合sql语句,经编译创建并保存在数据库中,用户可通过存储过程的名字调用执行。存储过程核心思想就是数据库sql语言层面的封装与重用性。使用存储过程可以较少应用系统的业务复杂性,但是会增加数据库服务器系统的负荷,所以在使用时需要综合业务考虑。
2、基本语法格式
create procedure sp_name ([proc_parameter[,...]]) [characteristic ...] routine_body
- 案例一:计算消费折扣
-- 创建存储过程 drop procedure if exists p01_discount ; create procedure p01_discount(in consume numeric(5,2),out payfee numeric(5,2)) begin -- 判断收费方式 if(consume>100.00 and consume<=300.00) then set payfee=consume*0.8; elseif (consume>300.00) then set payfee=consume*0.6; else set payfee = consume; end if; select payfee as result; end ; -- 调用存储过程 call p01_discount(100.0,@discount);
- 案例二:while..do写数据
提供一张数据表
create table `t03_proced` ( `id` int(11) not null auto_increment comment '主键id', `temp_name` varchar(20) default null comment '名称', primary key (`id`) ) engine=innodb default charset=utf8 comment='触发器写数据';
存储程序
根据传入的参数,判断写入t03_proced表的数据条数。
drop procedure if exists p02_batch_add ; create procedure p02_batch_add(in count int(11)) begin declare temp int default 0; while temp < count do insert into t03_proced(temp_name) values ('pro_name'); set temp = temp+1 ; end while; end ; -- 测试:写入10条数据 call p02_batch_add(10);
3、注意事项
- 业务场景
存储过程在实际开发中的应用不是很广泛,通常复杂的业务场景都在应用层面开发,可以更好的管理维护和优化。
- 执行速度
假如在单表数据写入的简单场景下,基于应用程序写入,或者数据库连接的客户端写入,相比存储过程写入的速度就会慢很多,存储过程在很大程度上没有网络通信开销,解析开销,优化器开销等。
二、mysql视图
1、基本概念
视图本身是一张虚拟表,不存放任何数据。在使用sql语句访问视图的时候,获取的数据是mysql从其它表中生成的,视图和表在同一个命名空间。视图查询数据相对安全,视可以隐藏一些数据和结构,只让用户看见权限内的数据,使复杂的查询易于理解和使用。
2、视图用法
现在基于用户和订单管理演示视图的基本用法。
- 基础表结构
create table v01_user ( id int(11) not null auto_increment comment '主键id', user_name varchar(20) default null comment '用户名', phone varchar(20) default null comment '手机号', pass_word varchar(64) default null comment '密码', card_id varchar(18) default null comment '身份证id', pay_card varchar(25) default null comment '卡号', primary key (id) ) engine=innodb default charset=utf8 comment '用户表'; create table v02_order ( id int(11) not null auto_increment comment '主键id', user_id int(11) not null comment '用户id', order_no varchar(32) default null comment '订单编号', good_name varchar(60) default null comment '商品名称', good_id int(11) default null comment '商品id', num int(11) default null comment '购买数量', total_price decimal(10,2) default null comment '总价格', primary key (id) ) engine=innodb default charset=utf8 comment '订单表';
- 基本语法
create or replace view view_name as select_statement
注意事项:表和视图共享数据库中相同的名称空间,因此,数据库不能包含具有相同名称的表和视图。
- 用户订单视图
create or replace view user_order_view as select t1.id,t1.user_name,t2.order_no,t2.good_id, t2.good_name,t2.num,t2.total_price from v01_user t1 left join v02_order t2 on t2.user_id = t1.id;
- 视图调用
这里和mysql的表查询基本一致,可以使用各种查询条件。
select * from user_order_view where user_name='cicada';
- 查看视图
show create view user_order_view ;
- 修改视图
alter view view_name as select_statement ;
- 删除视图
drop view [if exists] view_name ;
3、视图更新
在指定条件允许的情况下,可以通过在视图上操作更新,删除,甚至写入数据,进而更新视图所涉及的相关表。
update user_order_view set user_name='smile' where id='1';
这里就通过对视图执行更新操作,进而更新v01_user
表数据。如果视图定义时使用聚合函数,分组等特殊操作,则无法更新。mysql不支持在视图上创建触发器。
4、视图实现
- 临时表算法
服务器会把视图查询sql的数据保存在临时表中,临时表的结构和视图字段结构一致,这样是sql查询优化中最忌讳的操作,数据量稍微偏大,就会严重影响性能。如果视图无法和原有表产生一对一的映射关系,就会产生临时表,由此也可见视图并不是很简单,甚至是非常复杂的功能。
- 合并算法
服务器基于视图中使用的表执行查询,最后把查询结构合并后返回给客户端。
- 区别方法
执行如下查询语句,可以分析执行的性能参数。
explain select * from user_order_view ;
观察查询结果中select_type
字段,如果是derived
则说明使用临时表。这里sql执行分析的语法后面优化部分再详解。
5、注意事项
- 性能问题
mysql并不支持在视图中创建索引,使用视图的时候可能会引发很多查询性能问题,所以建议使用的时候要慎重,多角度审视和测试。
- 特殊用法
基于视图的查询,可以修改部分表结构,只要不是在视图中使用的字段,就不会影响视图的查询。
三、源代码地址
github·地址 https://github.com/cicadasmile/mysql-data-base gitee·地址 https://gitee.com/cicadasmile/mysql-data-base
下一篇: python 读取鼠标点击坐标的实例