本节内容:
1、视图
2、触发器
3、事务
4、存储过程
5、函数
6、流程控制
1.引子
MySQL这个软件想将数据处理的所有事情,能够在mysql这个层面上全部都做了,也就是说它想要完成一件事,
以后想开发的人,例如想写python程序的人,你就专门的写你自己的python程序,以后凡是关于数据的增删改查,
全部都在MySQL里面完成,也就是说它想实现一个数据处理与应用程序的一个完全的解耦和状态,
比如说,如果我是个应用程序员,我想要查询数据,我不需要自己写sql语句,只需要调用mysql封装好的一些功能,
直接调用这个功能就可以了,之前我们使用sql来进行数据的增删改查,
其实sql也可以算作一个开发语言,有专门招数据库开发的岗位,也就是说mysql想做这么一个事儿,
以后啊,专门有人写应用程序的开发,专门有人来写sql,来开发sql部分,
在数据库层面根据应用层的程序员的要求,把sql语句全部写好,各种复杂的需求全部帮你封装好,
封装成一个一个的功能,应用程序开发程序员在根据自己的需求来使用这些功能,直接调用就可以了,
这是mysql想要完成的事情,
但是咱们以后做开发,一般不会这么搞,一般招聘需求里面都会有一项是要会sql,
浅显的说是因为花最少的钱,做最多的事儿,
但是往深了说是因为公司里面一般不会用这些内置的功能去sql的工作,至于为什么,咱们学完mysql之后再说吧~~~
一、视图
作用:一张虚拟的表,写好后,可以方便直接调用查询某些内容
但是修改这张表,会对原始数据进行修改,这就涉及到数据安全问题
视图是一个虚拟表(非真实存在),是跑到内存中的表,真实表是硬盘上的表,怎么就得到了虚拟表,
就是你查询的结果,只不过之前我们查询出来的虚拟表,从内存中取出来显示在屏幕上,
内存中就没有了这些表的数据,但是下次我要是想用这个虚拟表呢,没办法,只能重新查一次,每次都要重新查。
其本质是【根据SQL语句获取动态的数据集,并为其命名】,
用户使用时只需使用【名称】即可获取结果集,可以将该结果集当做表来使用。
我们把重复用的这些sql逻辑封装起来,
然后下次使用的时候直接调用这个封装好的操作就可以了,这个封装起来的操作就类似我们下面要说的视图
1、为什么要用视图:
使用视图我们可以把查询过程中的临时表摘出来,保存下来,用视图去实现,
这样以后再想操作该临时表的数据时就无需重写复杂的sql了,直接去视图中查找即可,
但视图有明显地效率问题,并且视图是存放在数据库中的,
如果我们程序中使用的sql过分依赖数据库中的视图,即强耦合,那就意味着扩展sql极为不便,因此并不推荐使用
(但是有些公司也在使用这种方式)
2、创建视图
临时表的应用:
#查询李平老师教授的课程名
mysql> select cname from course where teacher_id = (select tid from teacher where tname='李平老师'); #子查询的方式
#子查询出临时表,作为teacher_id等判断依据
select tid from teacher where tname='李平老师'
# 创建视图的语法:
#语法:CREATE VIEW 视图名称 AS SQL语句
创建视图示例
3、使用视图
我们不应该修改视图中的记录,
而且在涉及多个表的情况下是根本无法修改视图中的记录的,
名字
4、修改视图
语法:ALTER VIEW 视图名称 AS SQL语句
这基本就和删掉视图重新创建一个视图的过程是一样的,修改视图没什么好讲的,
这里就简单提一下,就不讲啦~~,还不如我们直接删掉,再重新创建呢
mysql> alter view teacher_view as select * from course where cid>3;
Query OK, 0 rows affected (0.04 sec)
mysql> select * from teacher_view;
+-----+-------+------------+
| cid | cname | teacher_id |
+-----+-------+------------+
| 4 | xxx | 2 |
| 5 | yyy | 2 |
+-----+-------+------------+
2 rows in set (0.00 sec)
5、删除视图
语法:DROP VIEW 视图名称
DROP VIEW teacher_view
二、触发器
使用触发器可以定制用户对某一张表的数据进行【增、删、改】操作时前后的行为,自动触发
注意:没有查询,
在进行增删改操作的时候,触发的某个操作,称为触发器,
也就是增删改的行为触发另外的一种行为,
触发的行为无非就是sql语句的事情,及自动运行另外一段sql语句。
来看一下触发器怎么来创建:
1、创建触发器
语法:
delimiter // # 先将sql语句的结束符分号改成delimiter后面的//
CREATE TRIGGER tri_after_insert_cmd AFTER INSERT ON cmd FOR EACH ROW #在你cmd表插入一条记录之后触发的。
BEGIN #每次给cmd插入一条记录的时候,都会被mysql封装成一个对象,叫做NEW,里面的字段都是这个NEW的属性
sql语句
END// # 结束并执行,
注意事项:
1.里面的代码缩进,尽量开头不要有缩进,有可能会因此不能执行
2.起触发器的名字,最好要有意义,让人一看就知道是什么触发器
fe1:几种触发器创建示例
几种触发器创建示例
1、数据插入之后的触发器
特别的:NEW表示即将插入的数据行,OLD表示即将删除的数据行。
数据插入后触发的触发器
2、使用触发器
触发器无法由用户直接调用,而由对表的【增/删/改】操作被动引发的。
3、删除触发器
drop trigger tri_after_insert_cmd;
三、事务
事务用于将某些操作的多个SQL作为原子性操作,
也就是这些sql语句要么同时成功,要么都不成功
四大特征:
原子性、一致性、持久性、隔离性
简单来说:我给一个姑娘转账,姑娘那儿收到了200,你的账户上扣了200,
这两个操作是不是两个sql语句,这两个sql语句是你的应用程序发给mysql服务端的,
并且这两个sql语句都要一起执行,不然数据就错了,你想想是不是。
并且如果你通过应用程序发送这两条sql的时候,
由于网络问题,你只发送了一个sql过来,那只有一个账户改了数据,
另外一个没改,那数据是不是就出错了啊。这就是事务要完成的事情。
1、事务的具体示例
注意事项:
1、只要不进行commit操作,就没有保存下来,没有刷到硬盘上
2、rollback前面执行的任意一条sql语句出现了异常,就直接rollback,
数据就直接回到原来的状态了。但是执行了commit之后,rollback这个操作就没法回滚了
但是我们需要捕获一下异常,如何捕获呢
3、我们需要用存储过程来捕获异常,
事务的具体示例
四、存储过程
1、介绍
存储过程包含一系列可执行的sql语句,存储过程存放在mysql中,通过调用它的名字可以执行其内部的sql。
上面学的视图、触发器、事务虽然简化了应用程序级别写sql语句的复杂程度,但我们还是要在
应用程序上写sql,下面学的存储过程就是让我们不用写sql语句,
所有的sql语句,全部放在mysql里面,被mysql封装成存储过程,说白了它就是一个功能,
这个功能对应着一大堆的sql语句,
它的好处是我项目逻辑中需要的各种查询都可以让DBA或者你自己封装到存储过程里面,
以后使用的时候直接调用存储过程名就可以了,在开发应用的时候就简单了,
就不要应用程序员进行sql语句的开发了,但是你想如果你真的这么做了,
确实很有好处,简单很多,应用程序的开发和数据库sql语句的开发,完全的解耦了,
这样,专门的人做专门的事情,
专门招一个应用开发的人开发应用程序,招一个开发型DBA,会sql的开发,
他把sql写完之后,封装成一个个的存储过程,给应用程序员用就行了,
对不对,这个DBA就不单纯的是管理数据库系统了,还需要会写sql语句,
那这样你的应用程序开发的效率就高了,运行效率也提高了,
你开发应用程序的时候如果写了一堆的sql语句,这些语句是不是要通过网络传输,
传输到mysql服务端来执行,然后将结果返回给你的应用程序,那么在传输的时候,
你说好多的sql语句和简单的一个存储过程的名字,
哪个传输的速度快,哪个发送给服务端的速度快,
当然是单纯的一个存储过程的名字更快。
1、使用存储过程的优点:
1. 用于替代程序写的SQL语句,实现程序与sql解耦
2. 基于网络传输,传别名的数据量小,而直接传sql数据量大
2、使用存储过程的缺点:
1. 程序员扩展功能不方便
3、三种工作中的开发模式对比
名字
4、上面一大堆话的总结:程序与数据库结合使用的三种方式
方式一:
MySQL:存储过程
程序:调用存储过程
方式二:
MySQL:
程序:纯SQL语句
方式三:
MySQL:
程序:类和对象,即ORM(本质还是纯SQL语句)
2、创建简单的存储过程(无参)
3、创建存储过程(有参)
对于存储过程,可以接收参数,其参数有三类:
in 仅用于传入参数用
out 仅用于返回值用
inout 既可以传入又可以当作返回值
1、in:只传入参数:
#通过存储过程的传参来看,也能体现出我们学习的Python的灵活性,
传参不需要指定类型,也不需要声明这个参数是传入的还是返回出来的,
参数既可以传入,这个参数也可以直接通过return返回。
fe1:in在mysql中的示例和pymys中的使用示例
in:只传入参数
2、out:直接收返回值:
在mysql中调用,
需先定义变量,接收返回的状态,
这是MySQL中定义变量名的固定写法(set @变量名=值)
,可以自己规定好,0代表假(执行失败),1代表真(执行成功),
如果这个被改为1了,说明存储过程中的sql语句执行成功了
在pymysql中
只需要传参进去,任意参数,
pymysql,人家会帮你搞定,pymysql其实会帮你写成这样:
第一个参数变量名:@_p3_0=3,第二个:@_p3_1=0,
也就是pymysql会自动帮你对应上一个变量名,
pymysql只是想让你写的时候更方便
fe2:out的在mysql和pymysql中的使用示例
out的使用示例
3、inout:既可传入又可以返回值:
fe3:inout在mysql和pymysql的使用示例
inout在mysql和pymysql的使用示例
4、存储过程结合事务来写:
存储过程接合事务的示例
4、执行存储过程
1、在MySQL中执行存储过程:
2、在python中基于pymysql来执行存储过程:
5、删除存储过程
drop procedure proc_name;
五、函数
MySQL中提供了许多内置函数,但是注意,这些函数只能在sql语句中使用,
不能单独调用昂,例如:其实下面的有些函数我们都已经用过了,
其他的如果你们用到了,咱们再过来查吧,好不?
相关函数介绍