数据库高级部分
1.视图(view)
视图是有一张表或多张表的查询结果构成的一张虚拟表,使用的好处是:
当在使用多表查询时,sql语句可能会非常的复杂,每次都编写一遍会相当麻烦,所以可以通过视图帮我们节省sql的编写重复使用。
另一个作用是,我们可以使用不同的视图来开放不同数据的访问,限定展示出想要展示的部分
注意:由于是一张虚拟表,视图中的数据实际上来源于其他其他表,所以在视图中的数据不会出现在硬盘上
创建视图
CREATE [OR REPLACE] VIEW view_name [(column_list)]
AS select_statement
2.触发器(trigger)
触发器是一段与表有关的mysql程序,当这个表在某个时间点发生了某种事件时 将会自动执行相应的触发器程序
时间点表示当在事件发生前使用before | 事件发生后 使用after
事件包括update,delete,insert
触发器包含两个对象
old :update,delete中可用
new :update,insert 中可用
可以用于:当表的数据被修改时,自动记录一些数据,执行一些sql语句
3.事务(transaction)
事务就是一系列sql语句的组合,是一个整体。
事务的特点:
原子性,指的是这个事务中的sql语句是一个整体,不能拆分,要么都执行,要么全都失败
一致性, 事务执行结束后,表的关联关系一定是正确的,不会发送数据错乱
隔离性,事务之间相互隔离,数据不会互相影响,即使操作了同一个表 , 本质就是加锁,根据锁的粒度不同分为几个隔离级别
持久性,事务执行成功后数据将永久保存,无法恢复
脏读:所谓的脏读,其实就是读到了别的事务回滚前的脏数据。比如事务B执行过程中修改了数据X,在未提交前,事务A读取了X,而事务B却回滚了,这样事务A就形成了脏读。
也就是说,当前事务读到的数据是别的事务想要修改成为的但是没有修改成功的数据。
不可重复读:事务A首先读取了一条数据,然后执行逻辑的时候,事务B将这条数据改变了,然后事务A再次读取的时候,发现数据不匹配了,就是所谓的不可重复读了。
也就是说,当前事务先进行了一次数据读取,然后再次读取到的数据是别的事务修改成功的数据,导致两次读取到的数据不匹配,也就照应了不可重复读的语义。
幻读:事务A首先根据条件索引得到N条数据,然后事务B改变了这N条数据之外的M条或者增添了M条符合事务A搜索条件的数据,导致事务A再次搜索发现有N+M条数据了,就产生了幻读。
使用事务:
start transaction:开启事物,在这条语句之后的sql将处在同一事务,并不会立即修改数据库
commit:提交事务,让这个事物中的sql立即执行数据的操作,
rollback:回滚事务,是用来取消这个事物,这个事物则不会对数据库中的数据产生任何影响,比如当一个事务执行过程中出现了异常这种情况可使用rollback来回滚事务
savepoint:保存点,可以在rollback指定回滚到某一个固定位置 ,也就是回滚一部分
4.存储过程(procedure)
存储过程是一组任意的sql语句集合,在mysql中,调用存储过程会执行其包含的所有sql语句;与python中函数类似
调用时用set设置变量,call来调用存储过程
5.函数
sql语言中除了内置函数可以自定义函数
通过create 创建函数,包括函数名,函数体,返回值的类型和返回值
6.备份与恢复
使用自带的mysqldump.exe来备份,可以备份具体的表,库,或者所有的库至一个文件里
mysqldump -u用户名 -p密码 要备份的内容(数据库 表名1 表名2) .... > 文件路径....
恢复数据:
没有登录mysql :mysql < 文件路径
已经登录了MySQL :source 文件路径
7.流程控制
主要包括一些sql语法:
if then/case(选择执行)/declare (定义变量)/while,loop,repeat(循环)
查询语法中正则匹配的用法 是在条件判断通过regexp中加入正则匹配来筛选,注意不能加入类似\w这样的符号
8.用户管理
主要为了控制权限,让不同开发者,仅能操作属于自己的业务范围内的数据
create user 用户名@主机地址 identified by "密码";
# 注意:操作用户 只能由root账户来进行
# 删除 将同时删除所有权限
drop user 用户名@主机地址;
9.权限管理
涉及到的表
user 与用户相关信息
db用户的数据库权限信息
tables_priv 用户的表权限
columns_priv 用户的字段权限
语法:
grant all on *.* to 用户名@主机地址 identified by "密码";
all表示的是对所有字段的增删改查的权限
*.*表示的是所有库的所有表
还可以具体到某个库,某个表,或者某个字段,可以通过相应的tables_priv,columns_priv来查看是否获取了权限
收回权限
revoke all on *.* from 用户名@主机地址;
同样也可以回收具体的库和表
刷新权限
flush privileges;
还可以通过@% 可以授予某个用户在任何主机上登录
grant all on *.* to jack10@"%" identified by "123";
10.pymysql
pymysql是一个第三方模块,帮我们封装了mysql的一些功能,比如建立连接,用户认证,sql的执行以及结果的获取
1. 连接服务器,获取连接对象(本质上就是封装号的socket)
conn = pymysql.connect(
host = "127.0.0.1", #如果是本机 可以忽略
port = 3306, # 如果没改过 可以忽略
user = "root", #必填
password = "111", #必填
database = "day42" #必填)
2.通过连接拿到游标对象
# 默认的游标返回的是元组类型 不方便使用,需要更换字典类型的游标
c = conn.cursor(pymysql.cursors.DictCursor)
3.执行sql
sql = "select * from table1"
res = c.execute(sql)
查询语句将返回查询的结果数量
4.提取结果
print(res)
print(c.fetchall())
# 移动光标 参数移动的位置 mode指定相对或绝对
# c.scroll(1,mode="absolute")
# print(c.fetchall())
# print(c.fetchmany(1))
# print(c.fetchone())
5.关闭连接
c.close()
conn.close()
sql注入攻击
指的是,一些程序员,在输入数据时,按照sql的语法规范,提交了用于攻击性目的的数据
比如我们在登录用户名密码时,在输入用户名时使用sql语句,可以通过--加空格注释直接跳过后面的密码,或者可以直接注释掉用户名和密码
若要避免这个问题,需要在服务器端执行sql语句之前做sql的验证
将输入的用户名密码放入execute(sql,(name,))执行语句中执行
pymysql还可以调用存储过程
若创建了一个存储过程
可以先通过callproc来传入参数,传入的参数会自动定义成变量,变量名的定义方式为@_过程名称_参数的索引
在通过execute来执行,最后打印结果