1.什么是视图?
视图就是通过查询得到的一张虚拟表,然后保存下来,下次直接使用即可
2.为什么要用视图?
如果要频繁使用一张虚拟表,可以不用重复查询
3.如何使用视图?
create view 视图名 as select * from 表 inner join 表 on 条件;
强调
1.在硬盘中,视图只有表结构文件,没有表数据文件
2.视图一般只适用于查询,不推荐修改视图的数据,如果修改的话会将原数据进行修改。
修改视图:当组成视图的基本表发生变化后可以通过修改视图来保持于基本表的一致性
CREATE OR replace VIEW 视图名 AS SELECT * FROM 基本表;
删除视图
drop view 视图名;
为什么开发过程中不会使用视图
视图是mysql的功能,如果项目中使用大量的视图,在你想要扩充功能的时候如果这个视图需要对视图修改的话,就需要先将mysql这边的视图修改后去应用程序中修改对应的sql语句,这样的话需要跨部门沟通,所以通常不会使用视图,而是通过修改sql语句进行扩展功能。
触发器
是一种保证数据完整性的方法。由事件来触发并非由程序调用和手动启动。
为什么使用触发器?
触发器是针对于对于某张表数据增insert,改update,删delete的行为,这类操作行为一旦执行就会触发触发器的执行,即自动执行另一端sql代码
创建触发器语法
#针对插入:
create trigger 触发器名 after insert on 表名 for each row
begin
sql 代码。。。
end
create trigger 触发器名 before insert on 表名 for each row
begin
sql代码。。。
end
#针对删除:
create trigger 触发器名 after delete on 表名 for each row
begin
sql代码...
end
create tigger 触发器名 before delete on 表名 for each row
begin
sql代码,,,
end
#针对修改
create tigger 触发器名 after update on 表名 for each rrow
begin
sql代码。。。
end
create tigger 触发器名 before update on 表名 for each row
end
举个栗子
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'));
create table errlog(id int primary key auto_increment,err_cmd char(64),err_time datetime);
delimiter $$ #将mysql默认的结束符由;换成$$针对本次有效
create trigger tri_after_insert_cmd after insert on cmd for each row
begin
if NEW.success = 'no' then #新纪录会被mysql封装成new对象
insert into errlog(err_cmd,err_time) values(NEW.cmd,NEW.sub_time);
end if;
end $$
delimiter; #结束后将结束符改回来
insert into cmd(user,priv,cmd,sub_time,success)values('egon','0755','ls -l /etc',NOW(),'yes'),('egon','0755','cat /etc/passwd',NOW(),'no'),('egon','0755','useradd xxx',NOW(),'no'),('egon','0755','ps aux',NOW(),'yes'); #向表cmd中插入记录,触发触发器,根据if的条件决定是否插入错误日志。
select * from errlog; #查看errlog表记录
drop trigger tri_after_insert_cmd; #删除触发器
事务
什么是事务
开启一个事物可以包含一些sq语句,这些sql语句要么同时成功要么全部都无法成功,称之为事物的原子性
事务的作用:
保证了对数据操作的数据安全性
事务应该具有的四个属性:
原子性、一致性、隔离性、持久性。四个属性通常称为ACID特性
原子性(atomicity):一个事物是不可分割的工作单位,实务中包括的诸多操作要么做要么不做
一致性(consistency):事务必须是使数据库从一个一致性状态变成另一个一致性状态,一致性于原子性密切相关。
隔离性(isolation):一个事物不能被其他事务干扰。每个事务内部操作与使用数据对并发的其他事物都是隔离的,并发执行的各个事务之间不能互相干扰。
持久性(durability):持久性也称永久性(permanence),指一个事物一旦提交,他对数据库中数据的高边就应该是永久性的,接下来的其他操作或故障不应该对其影响。
事务操作命令
start transaction; #开启事务在修改事务之前
rollback; #回滚到上一个状态即事务记录时刻
commit; #开启事务之后只要没有commit操作,数据就没有真正刷新到硬盘,即可进行回滚。
存储过程
定义:存储过程包含了一系列的可执行的sql语句,存储过程调用它的名字可以执行其内部的一堆sql‘
三种开发模式
第一种
'''
应用程序:只需要开发应用程序的逻辑
mysql:编写好存储过程,以供应用程序调用
优点:开发效率与执行效率都高
缺点:考虑到认为因素,跨部门沟通等问题,会导致扩展性差
'''
第二种
'''
应用程序:除了开发应用程序的逻辑,还需要编写原生sql
优点;比方式一扩展性高(非技术性)
缺点:开发效率,执行效率不如方式一
编写原生sql太过复杂,而且考虑到sql语句的优化环境
'''
第三种
'''
应用程序:开发应用程序的逻辑,不需要编写原生代码,iyu别人的框架来处理数据,ORM
优点:不用再编写原生sql,这就意味着开发效率比方式二高,同时兼容方式二的扩展性
缺点:执行效率比方式二还低
'''
创建存储过程
在mysql中调用
delimiter $$
create procedure p1(
in m int, # in表示这个参数必须只能是传入不能被返回出去
in n int,
out res int # out表示这个参数可以被返回出去,还有一个inout表示即可以传入也可以被返回出去
)
begin
select tname from teacher where tid > m and tid < n;
set res=0;
end $$
delimiter ;
# 小知识点补充,当一张表的字段特别多记录也很多的情况下,终端下显示出来会出现显示错乱的问题
select * from mysql.userG;
set @res = 10#res的值用来判断存储过程是否被执行成功的依据,所以先定义一个变量@res存储10
call p1(2,4,@res);
在python中调用(了解)
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 ;
函数
mysql的内置函数只能在sql语句中使用
CREATE TABLE blog ( id INT PRIMARY KEY auto_increment, NAME CHAR (32), sub_time datetime ); INSERT INTO blog (NAME, sub_time) VALUES ('第1篇','2015-03-01 11:31:21'), ('第2篇','2015-03-11 16:31:21'), ('第3篇','2016-07-01 10:21:31'), ('第4篇','2016-07-22 09:23:21'), ('第5篇','2016-07-23 10:11:11'), ('第6篇','2016-07-25 11:21:31'), ('第7篇','2017-03-01 15:33:21'), ('第8篇','2017-03-01 17:32:21'), ('第9篇','2017-03-01 18:31:21'); select DATE_FORMAT(sub_time,'%Y-%m-%d'),count(id) FROM blog group by DATE_FORMAT(sub_time,'%Y-%m-%d');
流程控制
#if 条件 delimiter // CREATE PROCEDURE proc_if () BEGIN declare i int default 0; if i = 1 THEN SELECT 1; ELSEIF i = 2 THEN SELECT 2; ELSE SELECT 7; END IF; END // delimiter ; #where循环 # while循环 delimiter // CREATE PROCEDURE proc_while () BEGIN DECLARE num INT ; SET num = 0 ; WHILE num < 10 DO SELECT num ; SET num = num + 1 ; END WHILE ; END // delimiter ;