一、视图
1.什么是视图
视图本质是一张虚拟的表
2.为什么要用
为了原表的安全
只要有两大功能
1.隐藏部分数据,开放指定数据
2.视图可以将查询结果保存,减少sql语句的次数
特点:
1.视图使用永久保存的,而且保存的仅仅是一条 as sql语句
2.每次对视图的查询,都是再次执行了保存的sql语句
3.对于视图的任何修改都会同步到原表
3.如何使用
语法:
create view 视图名 as select * from 原表名;
验证:对视图的任何修改会改变原表
#查看原表 select * from dept; +----+--------+ | id | name | +----+--------+ | 1 | 市场 | | 2 | 行政 | | 3 | 财务 | +----+--------+ #创建视图并查看 create view test_view as select * from dept; select * from test_view; +----+--------+ | id | name | +----+--------+ | 1 | 市场 | | 2 | 行政 | | 3 | 财务 | +----+--------+ #insert测试 #往视图插入一条数据 insert into test_view value(4,'公关'); select * from test_view; +----+--------+ | id | name | +----+--------+ | 1 | 市场 | | 2 | 行政 | | 3 | 财务 | | 4 | 公关 | +----+--------+ #查看原表 select * from dept; +----+--------+ | id | name | +----+--------+ | 1 | 市场 | | 2 | 行政 | | 3 | 财务 | | 4 | 公关 | +----+--------+ #证明了,对视图的任何修改操作,会对原表造成一样的操作
二、sql注入
1.什么是sql注入攻击
一些了解sql语法的用户,可以输入一些关键字或合法sql,来导致原始的sql逻辑发生变化 从而跳过登录验证或者删除数据库
2.如何使用sql注入
案例一
import pymysql conn=pymysql.Connect( user="root", password="root", host="localhost", database="day42", charset="utf8" ) cursor=conn.cursor(pymysql.cursors.DictCursor) name=input('user:') pwd=input('password:') sql="select *from user where name='%s' and password='%s';"%(name,pwd) print(sql) #如果此时我输的用户名是root' -- #那么sql=select *from user where name='root' -- ' and password='sdf'; # -- 用于注释,这样的结果会导致密码验证变成了注释里的内容 #无论密码正确与否,只要用户正确就可以登陆成功 res=cursor.execute(sql) print(res) if res: print('successful') else: print('error') cursor.close() conn.close()
案例二
import pymysql conn=pymysql.Connect( user="root", password="root", host="localhost", database="day42", charset="utf8" ) cursor=conn.cursor(pymysql.cursors.DictCursor) name=input('user:') pwd=input('password:') sql="select *from user where name='%s' and password='%s';"%(name,pwd) print(sql) #如果此时我输的用户名只要有 ' or 1=1 -- 出现 #那么sql=select *from user where name='asdsad' or 1=1 -- ' and password='sdawd'; #无论用户名密码正确与否,where筛选的结果永远是True res=cursor.execute(sql) print(res) if res: print('successful') else: print('error') cursor.close() conn.close()
3.如何预防sql注入漏洞
从客户端入手,接受用户输入的数据时,可以加上限制,比如不能输:-- ' ; where 等等
但是这样只能避免,黑客从你的客户端软件注入 sql,无法避免间人攻击(在你的客户端和服务器中间加一个中转服务器)
中间人攻击可以绕过了客户端的输入限制
可以将验证放到服务端
import pymysql conn=pymysql.Connect( user="root", password="root", host="localhost", database="day42", charset="utf8" ) cursor=conn.cursor(pymysql.cursors.DictCursor) name=input('user:') pwd=input('password:') sql="select *from user where name='%s' and password='%s';"%(name,pwd) res=cursor.execute(sql,args=(name,pwd)) #将要输入的内容放入execute的第二个参数里,pymysql模块自动帮我们解决sql注入的问题 print(res) if res: print('successful') else: print('error') cursor.close() conn.close()
三、事务
1.什么是事务
是一组sql语句集合
事务的特性:
1.原子性:
事务是一个整体,要么都执行完毕,要么一个都没执行
2.隔离性:
多个事务之间一定是并发的,那么并发一定会出现问题
1.脏读 读取到另一个事务未提交的数据
2.不可重复读 两次对同一记录的查询结果不一致
一个事务在查询 另一个事务在更新
3.幻读 对同一表中的查询结果数量不一致
一个事务在查询 另一个事务在添加或删除
3.一致性:
在这个事物执行完成后,事务中所进行的修改也都完成了,这样一来就保证了数据的完整性
4.持久性
当事务执行完毕后,事务对数据的修改都是持久性的、不可恢复的
2.如何使用
#语法 #1.开启一个事务 start transaction #2.sql语句 ........ #3.事务执行完毕后 使用commit来提交 一旦提交就不可恢复了 commit #4.在事务还未提交时我们可以使用rollback来回滚 默认回滚到事务开始前的状态 rollback
四、存储过程
1.什么是存储过程
你可以理解为mysql的编程语言
他的作用, 可以将你的程序业务逻辑放到mysql中来处理
这样可以降低网络访问次数 从而提高你的程序效率
既然如此,你不能把所有与数据存储相关的业务逻辑全都放mysql中?
能,但是对于公司而言,需要再请一个mysql开发者
对于你个人来说,提高沟通成本
2.三种开发的模型
方案一
应用程序: 处理逻辑,需要手动编写 sql语句
mysql:
优点:执行效率高
缺点: 开发效率低
方案二
应用程序:
mysql :处理逻辑,mysql开发者来编写,应用程序开发者不需要需要手动编写 sql语句
优点: 应用程序开发效率高
缺点: 执行效率略低,沟通成本增高
方案三
使用 ORM(object relation map) 对象关系映射
自动帮你生成对应的sql语句,比如你要注册用户,本来要写insert语句,现在使用orm调用save(用户对象)
优点:开发效率高
缺点:执行效率降低
3.语法
delimiter //#更换mysql的换行符 create procedure 过程的名称 ({in,out,inout} 参数名称 数据类型) begin #具体的sql代码 end// delimiter ; #参数前面需要指定参数的作用 #in 表示该参数用于传入数据 #out 用于返回数据 #inout 即可传入 也可返回
4.流程控制
if语句
if 条件 then 语句1; elseif 条件 then 语句2; else 语句3; end if;
case语句
你给我一个值 我对它进行选择 然后执行匹配上的语句
case 变量名 when 值1 then 语句1; when 值2 then 语句2; when 值3 then 语句3; else 语句4; end case;
while语句
WHILE 条件 DO
语句.....
end WHILE;