数据库——视图、触发器、事务(重点)、存储过程、函数、流程控制、索引(除了事务,都是理论)
视图
什么是视图?
视图就是通过查询得到一张虚拟表,然后保存下来,下次直接使用即可
为什么要用视图
如果要频繁使用一张虚拟表,可以不用重复查询
如何用视图?
# 创建视图
create view 视图名 as sql语句;
# 例子
create view teacher2course as
select * from teacher inner join course on teacher.tid = course.teacher_id;
注意
1、在硬盘中,视图只有表结构文件,没有表数据文件
2、视图通常是用于查询,尽量不要修改视图中的数据
# 删除视图
drop view 视图名;
开发过程中不推荐使用视图
触发器
在满足对某张表的数据进行增、删、改的情况下,自动触发的功能称之为触发器
为什么要用触发器?
触发器专门针对用户对表的操作,一旦操作,就会触发触发器的执行,就会自动执行另外一段SQL代码
创建触发器语法
# 针对插入
# 指定触发器被触发的时刻,它有两个选项关键字 defore 和关键字 after 用于表示触发器是在激活它的语句之前或者之后触发。如果希望验证新数据是否满足使用限制,则使用 before
create trigger 触发器名 after insert into on 表名 for each row begin
sql语句...
end
create trigger 触发器名 before insert into on 表名 for each row begin
sql语句...
end
# 针对删除
create trigger 触发器名 after delete on 表名 for each row begin
sql语句...
end
create trigger 触发器名 before delete on 表名 for each row begin
sql语句...
end
# 针对修改
create trigger 触发器名 after update on 表名 for each row begin
sql语句...
end
create trigger 触发器名 before update on 表名 for each row begin
sql语句...
end
# 删除触发器
drop trigger 触发器名;
事务
什么是事务?
是数据库操作的最小工作单元,是作为单个逻辑工作单元执行的一系列操作;这些操作作为一个整体一起向系统提交,要么都执行、要么都不执行
事务的作用
保证了对数据操作的数据安全性
事务的四大特性
1、原子性:一个事务是一个不可分割的工作单位,事务中的操作,要么都做,要么都不做
2、一致性:事务执行的结果必须是从一个一致性状态变到另一个一致性状态
3、隔离性:一个事务内部的操作及使用的数据对其他并发事务是隔离的,并发的各个事务之间不能互相干扰
4、持久性:也称永久性,事务一旦提交,它对数据库中的改变就是永久性的
如何使用事务?
create table user(
id int primary key auto_increment,
name char(32),
balance int
);
insert into user(name,balance)
values
('wsb',1000),
('egon',1000),
('ysb',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元
# 回滚到上一个状态(回滚到初始状态,就是开启事务操作那一步)
rollback;
# 开启事务之后,只要没有执行commit操作,数据其实都没有真实的写入硬盘
# 开启事务检测操作是否完整,不完整主动回滚到上一个状态,如果完整就应该执行commit操作
commit;
存储过程
存储过程包含了一系列可执行的SQL语句,存储过程存放于MySQL中,通过调用它的名字可以执行其内部的一堆SQL
三种开发模型
第一种
"""
应用程序:只需要开发应用程序的逻辑
mysql:编写好存储过程,以供应用程序调用
优点:开发效率,执行效率都高
缺点:考虑到人为因素、跨部门沟通等问题,会导致扩展性差
"""
第二种
"""
应用程序:除了开发应用程序的逻辑,还需要编写原生sql
优点:比方式1,扩展性高(非技术性的)
缺点:
1、开发效率,执行效率都不如方式1
2、编写原生sql太过于复杂,而且需要考虑到sql语句的优化问题
"""
第三种
"""
应用程序:开发应用程序的逻辑,不需要编写原生sql,基于别人编写好的框架来处理数据,ORM
优点:不用再编写纯生sql,这意味着开发效率比方式2高,同时兼容方式2扩展性高的好处
缺点:执行效率连方式2都比不过
"""
创建存储过程
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;
如何使用存储过程
# 大前提:存储过程在哪个库下面创建的只能在对应的库下面才能使用!!!
# 1、直接在mysql中调用
set @res=10 # res的值是用来判断存储过程是否被执行成功的依据,所以需要先定义一个变量@res存储10
call p1(2,4,10); # 报错
call p1(2,4,@res);
# 查看结果
select @res; # 执行成功,@res变量值发生了变化
# 2、在python程序中调用
pymysql链接mysql
产生的游表cursor.callproc('p1',(2,4,10)) # 内部原理:@_p1_0=2,@_p1_1=4,@_p1_2=10;
cursor.excute('select @_p1_2;')
# 3、存储过程与事务使用举例(了解)
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 ;
函数
例题
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'),count(id) from blog group by date_format(sub_time,'%Y-%m');
流程控制
# 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 ;
# 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 ;