mysql视图、触发事务、存储过程
视图
视图是一个虚拟表(非真实存在的),其本质就是根据SQL语言获取动态的数据集,并为其命名,用户使用时只需要使用名称即可获得结果集,可以将结果集当做表来使用。
视图是存在数据库中的,如果我们程序中使用的sql过分依赖数据库的视图,即强耦合,那就意味着扩展不方便。
创建视图:
create view view_name as select * from table1 inner join table2 on table1.id=table2.sid;
使用视图以后就无需每次都重写子查询的sql,但是效率并不高,不如我们写子查询的效率高。
致命问题是视图是存放在数据库的,如果我们 程序中的sql过分依赖数据库中存放的视图 ,就意味着一旦sql需要修改且涉及视图的部分 就必须去数据库中修改,通常是由专门的DBA负责的,要是想要修改,必须付出大量的沟通成本才会帮我们去修改。
我们不应该修改视图中的记录的,而且涉及多个表的情况下根本是无法修改视图中的记录的。
修改视图:
alter view view_name as sql语句
删除视图:
drop view view_name;
触发器
触发器是在满足某种条件,自动触发的功能
应用场景:专门针对我们某一张表数据进行增删改的行为,这类行为一旦执行就会触发触发器的执行,即自动运行另一段sql代码。
创建触发器:
1.插入前
create trigger tri_before_insert_tb1 before insert on tb1 for each row begin …… end
2.插入后
create trigger tri_after_insert_tb1 after insert on tb1 for each row begin …… end
3.例子
#准备表
CREATE TABLE cmd (
id INT PRIMARY KEY auto_increment,
USER CHAR (32),
priv CHAR (10),
cmd CHAR (64),
sub_time datetime, #提交时间
success enum ('yes', 'no') #0代表执行失败
);
CREATE TABLE errlog (
id INT PRIMARY KEY auto_increment,
err_cmd CHAR (64),
err_time datetime
);
#创建触发器
delimiter //
CREATE TRIGGER tri_after_insert_cmd AFTER INSERT ON cmd FOR EACH ROW
BEGIN
IF NEW.success = 'no' THEN #等值判断只有一个等号
INSERT INTO errlog(err_cmd, err_time) VALUES(NEW.cmd, NEW.sub_time) ; #必须加分号
END IF ; #必须加分号
END//
delimiter ;
#往表cmd中插入记录,触发触发器,根据IF的条件决定是否插入错误日志
INSERT INTO cmd (
USER,
priv,
cmd,
sub_time,
success
)
VALUES
('aaaa','','ls -l /etc',NOW(),'yes'),
('aaaa','','cat /etc/passwd',NOW(),'no'),
('aaaa','','useradd xxx',NOW(),'no'),
('aaaa','','ps aux',NOW(),'yes');
注意:NEW表示即将插入的数据行,mysql每插入一条数据就会将其封装为一个对象new。OLD表示即将删除的数据行。
使用触发器
触发器是无法由用户直接使用的,对表的改数据操作是被动引发的。
删除触发器
drop trigger tri_after_insert_cmd;
事务
开启一个事务可以包含一系列sql语句,这些语句要么 同时成功,要么一个都不成功,这称为事务的原子性。事务主要用于交易类。
事务将某些操作的多个SQL作为原子操作,一旦出现某些错误,即可回滚到原来状态(commit了就不能改了),从而保证数据的完整性。
开启事务:
#数据表准备
create table user(
id int primary key auto_increment,
name char(32),
balance int
); #数据准备
insert into user(name,balance) values
('aaa',1000),
('bbb',1000),
('ccc',1000);
#原子操作
start transaction;
update user set balance=900 where name='wsb'; #买支付100元
update user set balance=1010 where name='egon'; #中介拿走10元
update user set balance=1090 where name='ysb'; #卖家拿到90元
commit;
#出现异常,回滚到初始状态
start transaction;
update user set balance=900 where name='aaa'; #买支付100元
update user set balance=1010 where name='bbb; #中介拿走10元
uppdate user set balance=1090 where name='ccc'; #卖家拿到90元,出现异常没有拿到
rollback;
#rollback只有在commit之前才能回滚到原来状态,commit之后数据在硬盘上改变了,就无法回滚了 commit;
存储过程
存储过程是完全有专门的开发人员开发管理,程序开发人员需要跨部门沟通,导致扩展性差。
存储过程包含了一系列可执行的sql语句,存储过程存放在mysql中,通过调用它的名字可以执行其内部的一堆sql。
使用存储过程的优点:
- 用于替代程序写的SQL语句,实现程序与SQL解耦
- 基于网络传输,用存储过程只需要传输封装好的别名,而直接传输数据量大,网络IO慢。
缺点:程序员扩展不方便
三种开发模型:
1.应用程序:只需开发应用程序的逻辑
mysql编写好存储过程,以供应用程序调用
优点:开发效率、执行效率高
缺点:考虑到人为因素、跨部门沟通导致扩展性差
2.应用程序:除了开发应用程序的逻辑,还需要编写原生的sql
优点:比方式一,扩展性高(非技术)
缺点:开发效率、执行效率都不如方式1
编写原生sql太过复杂,需要考虑sql优化问题
3.应用程序:开发应用程序的逻辑,不需要编写原生sql,基于别人写的框架来处理数据,ORM
优点:不用再编写原生sql,比原生开发效率高,同时兼容扩展性高的好处
缺点:执行效率连方式2都比不过3
创建存储过程
delimiter $$
create procedure p1( #创建存储过程p1
in m int, #mysql中参数必须先规定类型和用途(in,out,inout)
in n int,
out res int #res用于接收返回值
)
begin
select tname from teacher where tid > m and tid < n;
set res=0;
end $$
delimiter ;
如何用存储过程
a、直接在mysql中调用
set @res=10 #mysql中变量的定义要用@abc的形式
call p1(2,4,@res);
select @res; #查看结果
b、在python程序中调用
import pymysql
conn=pymysql.connect(
host='127.0.0.1',
port=3306,
user='root',
password='',
charset='utf8',
database='db42'
)
cursor=conn.cursor(pymysql.cursors.DictCursor)
cursor.callproc('p1',(2,4,10)) #@_p1_0=2,@_p1_1=4,@_p1_2=10 #pymysql帮助对传入变量进行以上变形
print(cursor.fetchall())
cursor.execute('select @_p1_2;') #查看返回值,确认执行结果
print(cursor.fetchone())
cursor.close()
conn.close()
事务的使用 (事务+存储过程)
delimiter //
create PROCEDURE p5(
OUT p_return_code tinyint
)
BEGIN
DECLARE exit handler for sqlexception #如果出现错误,执行
BEGIN
-- ERROR
set p_return_code = 1;
rollback;
END;
DECLARE exit handler for sqlwarning #如果出现警告,执行
BEGIN
-- WARNING
set p_return_code = 2;
rollback;
END;
START TRANSACTION; #事务的应用
update user set balance=900 where id =1;
update user123 set balance=1010 where id = 2;
update user set balance=1090 where id =3;
COMMIT;
-- SUCCESS
set p_return_code = 0; #0代表执行成功
END // delimiter ;
在python中调用存储过程
import pymysql conn=pymysql.connect(
host='127.0.0.1',
port=3306,
user='root',
password='root',
charset='utf8',
database='mydb' )
cursor=conn.cursor(pymysql.cursors.DictCursor)
cursor.callproc('p6',(100,)) #@_p5_0 = 100
cursor.execute('select @_p6_0')
print(cursor.fetchone())
cursor.close()
conn.close()
删除存储过程:
prop procedure proc_name;
函数
1、强调:mysql内置的函数只能在sql语句中使用
mysql> select date_format(sub_time,'%Y-%m'),count(id) from blog group by date_format(sub_time,'%Y-%m');
2、补充
a、select * from s1 \G #表字段太多(字段行显示不全)时,用\G将表竖着显示出来: row1 哪些字段: 对应的内容,row2。。。
b、视图、触发器、事务、存储过程、函数、流程控制皆是在库下面建立
流程控制 (if,while,case)
#case
select
case
when name = 'aaa' then
name
when name = 'bbb' then
concat(name,'_BIGSB')
else
concat(name,'_SB')
end
from emp;
mysql视图、触发事务、存储过程的更多相关文章
- MySQL 视图触发器事务存储过程函数
事务 致命三问 什么是事务:开启了一个包含多条SQL语句的事务,这些SQL语句要么都执行成功,要么有别想成功:例如A向B转账,二人账户并不属于一家银行,在转账过程中由于网络问题,导致A显示转账 成功 ...
- MySQL 视图 触发器 事务 存储过程 函数 流程控制 索引与慢查询优化
视图 1.什么是视图? 视图就是通过查询得到的一张虚拟表,然后保存下来,下次可直接使用 2.为什么要使用视图? 如果要频繁使用一张虚拟表,可以不用重复查询 3.如何使用视图? create view ...
- MySQL——视图/触发器/事务/存储过程/函数/流程控制
一 视图 视图是一个虚拟表(非真实存在),其本质是[根据SQL语句获取动态的数据集,并为其命名],用户使用时只需使用[名称]即可获取结果集,可以将该结果集当做表来使用. 使用视图我们可以把查询过程中的 ...
- MySQL视图,触发器,事务,存储过程,函数
create triggr triafterinsertcmdlog after insert on cmd_log FOR EACH ROW trigger_body .#NEW : 代表新的记录 ...
- Mysql 视图 游标 触发器 存储过程 事务
Mysql 视图 触发器 存储过程 游标 游标是从数据表中提取出来的数据,以临时表的形式存放在内存中,在游标中有一个数据指针,在初始状态下指向的是首记录,利用fetch语句可以移动该指针,从而对游标中 ...
- mysql 视图,事务,存储过程,触发器
一 视图 视图是一个虚拟表(非真实存在),是跑到内存中的表,真实表是硬盘上的表.使用视图我们可以把查询过程中的临时表摘出来,保存下来,用视图去实现,这样以后再想操作该临时表的数据时就无需重写复杂的sq ...
- MySQL拓展 视图,触发器,事务,存储过程,内置函数,流程控制,索引,慢查询优化,数据库三大设计范式
视图: 1.什么是视图 视图就是通过查询得到一张虚拟表,然后保存下来,下次直接使用即可 2.为什么要用视图 如果要频繁使用一张虚拟表,可以不用重复查询 3.如何使用视图 create view tea ...
- python mysql 视图 触发器 事物 存储过程 用户授权 数据备份还原
###################总结########### 视图是一个虚拟表(非真实存在) 是跑在内存中的表,真实表是在硬盘上的表 使用视图我们可以把查询过程中的临时表摘出来,保存下来,用视图去 ...
- Python11/26--mysql之视图/触发器/事务/存储过程
视图: 1.什么是视图 视图就是通过查询得到一张虚拟表,然后保存下来,下次用的时候直接使用即可 2.为什么用视图 如果要频繁使用一张虚拟表,可以不用重复查询 3.如何用视图 select * from ...
- MySQL视图view/存储过程和函数的使用
p.p1 { margin: 0.0px 0.0px 0.0px 0.0px; font: 12.0px "Helvetica Neue"; color: #454545 } p. ...
随机推荐
- Lodop打印旋转180度 倒着打
方法1:打印出来后,直接把纸张倒过来.如果本身是白纸,打印机出纸内容是倒着的,可以打出来后手动倒着把纸张正过来.如果本身不是白纸,需要打印的纸张上有背景,调整进纸方向.(如果是卷纸,卷纸背景是反的,查 ...
- tomcat9 点击bin目录下的startup.bat一闪而过
我装的是tomcat9免安装版,jdk版本是11,之后去tomcat bin目录下点击startup.bat闪退(好吧,只有想办法解决了) 博客中的解决办法五花八门,什么环境变量没配好....不过都不 ...
- BZOJ2480Spoj3105 Mod&BZOJ1467Pku3243 clever Y——EXBSGS
题目描述 已知数a,p,b,求满足a^x≡b(mod p)的最小自然数x. 输入 每个测试文件中最多包含100组测试数据. 每组数据中,每行包含3个正整数a,p,b. 当a=p ...
- C - A Simple Problem with Integers POJ - 3468 线段树模版(区间查询区间修改)
参考qsc大佬的视频 太强惹 先膜一下 视频在b站 直接搜线段树即可 #include<cstdio> using namespace std; ; int n,a[maxn]; stru ...
- Codeforces551 C. GukiZ hates Boxes
二分答案 + 贪心 传送门:$>here<$ $Solution$ 二分时间+贪心验证.思维难度主要在验证上,然而坑人的点却在n的取值上.那么先来谈如何验证.在已知时间的条件下,能否用一种 ...
- 用牛顿-拉弗森法定义平方根函数(Newton-Raphson method Square Root Python)
牛顿法(Newton’s method)又称为牛顿-拉弗森法(Newton-Raphson method),是一种近似求解实数方程式的方法.(注:Joseph Raphson在1690年出版的< ...
- Codeforces Round #511 (Div. 1) C. Region Separation(dp + 数论)
题意 一棵 \(n\) 个点的树,每个点有权值 \(a_i\) .你想砍树. 你可以砍任意次,每次你选择一些边断开,需要满足砍完后每个连通块的权值和是相等的.求有多少种砍树方案. \(n \le 10 ...
- Android 一些关于 Activity 的技巧
锁定 Activity 运行时的屏幕方向 Android 内置了方向感应器的支持.在 G1 中,Android 会根据 G1 所处的方向自动在竖屏和横屏间切换.但是有时我们的应用程序仅能在横屏 / 竖 ...
- CSS垂直翻转与水平翻转
/*水平翻转*/ .flipx { -moz-transform:scaleX(-1); -webkit-transform:scaleX(-1); -o-transform:scaleX(-1); ...
- luogu5019 [NOIp2018]铺设道路 (贪心)
和NOIp2013 积木大赛一模一样 我在堆一格的时候,我把它尽量地往右去延伸 于是如果对于一个i,a[i-1]<a[i],那i在之前一定只堆过a[i-1]那么多,所以要再堆a[i]-a[i-1 ...