首页 > 编程语言 >python四十四期---

python四十四期---

时间:2022-11-29 21:01:55浏览次数:42  
标签:事务 name python 查询 --- 四十四 where id select

昨日内容回顾

  • 多表查询的两种方式

    连表操作
    	inner join
     	left join
     	right join
    	ps:所需结论来自于多张表的字段 建议使用连表
    子查询
    	将SQL语句括号括起来当做另外一条SQL语句的条件
    	ps:所需结论来自于一张表的字段 可以使用子查询
    '''甚至两者在复杂SQL查询中需要混合使用'''
    
  • 小知识点的补充说明

    1.拼接相关操作
    	concat()  concat_ws()  group_concat()
    2.关键字exists
    	sql1 exists sql2
     	"""
     	if sql2:sql1
     	"""
    3.针对表操作的SQL补充
    	alter table 表名 rename\add\change\modify\drop 
    
  • 可视化软件之Navicat

    1.下载与安装
    2.基本使用
    	链接、创建、库、表、记录、外键
    	逆向数据库到模型
     	新建查询
     	运行、转储SQL文件
    
  • 多表查询练习题

    1.先确定需要涉及到几张表
    2.大致预览表结构与表数据
    3.根据已知条件确定切入点
    4.灵活运用所学内容去拼凑
    	将复杂的操作流程化 步骤化
    ps:一定要自己多练多敲
    
  • pymysql模块

    pip3 install pymysql
    
    
    import pymysql
    conn = pymysql.connect(
    	host,port,user,password/passwd,database/db,charset,autocommit
    )
    cursor = conn.cursor(...)
    cursor.execute(sql)
    cursor.fetchall()
    
    1.获取执行结果的方法也有类似于文件光标的特性
    2.针对增、删、改操作需要二次确认
    	conn.commit()
      	autocommit = True
    

今日内容概要

  • SQL注入问题
  • 视图
  • 触发器
  • 存储过程
  • 流程控制
  • 内置函数
  • 索引与慢查询优化

今日内容详细

SQL注入问题

怪像1:输对用户名就可以登录成功
怪像2:不需要对的用户名和密码也可以登录成功

SQL注入:利用特殊符合的组合产生特殊的含义 从而避开正常的业务逻辑
select * from userinfo where name='jason' -- kasdjksajd' and pwd=''
select * from userinfo where name='xyz' or 1=1 -- aksdjasldj' and pwd='' 

针对上述的SQL注入问题 核心在于手动拼接了关键数据 交给execute处理即可
sql = " select * from userinfo where name=%s and pwd=%s "
cursor.execute(sql, (username, password))

'''
补充说明
	executemany(sql,[(),(),(),()...])
'''

视图

视图就是通过查询得到一张虚拟表,然后保存下来,下次直接使用

create view teacher2course as
select * from teacher inner join course on teacher.tid = course.teacher_id;

1.视图的表只能用来查询不能做其他增删改操作
2.视图尽量少用 会跟真正的表产生混淆 从而干扰操作者

触发器

达到某个条件之后自动触发执行
在MySQL中更加详细的说明是触发器:针对表继续增、删、改操作能够自动触发
主要有六种情况:增前、增后、删前、删后、改前、改后
 
create trigger 触发器的名字 before/after insert/update/delete on 表名 for each row
begin
	sql语句
end

1.触发器命名有一定的规律
	tri_before_insert_t1
  	tri_after_delete_t2
 	tri_after_update_t2
2.临时修改SQL语句的结束符
	因为有些操作中需要使用分号 
    
 
触发器实际应用
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') #0代表执行失败
);

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 ;  # 结束之后记得再改回来,不然后面结束符就都是$$了

#往表cmd中插入记录,触发触发器,根据IF的条件决定是否插入错误日志
INSERT INTO cmd (
    USER,
    priv,
    cmd,
    sub_time,
    success
)
VALUES
    ('kevin','0755','ls -l /etc',NOW(),'yes'),
    ('kevin','0755','cat /etc/passwd',NOW(),'no'),
    ('kevin','0755','useradd xxx',NOW(),'no'),
    ('kevin','0755','ps aux',NOW(),'yes');

# 查询errlog表记录
select * from errlog;
# 查看所有的触发器
show triggers;
# 删除触发器
drop trigger tri_after_insert_cmd;

事务

事务的四大特性(ACID)
	A:原子性
		事务中的各项操作是不可分割的整体 要么同时成功要么同时失败
	C:一致性
    	使数据库从一个一致性状态变到另一个一致性状态
 	I:隔离性
    	多个事务之间彼此不干扰
  	D:持久性
     	也称永久性,指一个事务一旦提交,它对数据库中数据的改变就应该是永久性的
      
create table user(
id int primary key auto_increment,
name char(32),
balance int
);

insert into user(name,balance)
values
('jason',1000),
('kevin',1000),
('tank',1000);

# 修改数据之前先开启事务操作
start transaction;

# 修改操作
update user set balance=900 where name='jason'; #买支付100元
update user set balance=1010 where name='kevin'; #中介拿走10元
update user set balance=1090 where name='tank'; #卖家拿到90元

# 回滚到上一个状态
rollback;

# 开启事务之后,只要没有执行commit操作,数据其实都没有真正刷新到硬盘
commit;

"""
事务相关关键字
	start transaction;
	rollback
	commit
	savepoint
"""
在SQL标准中定义了四种隔离级别,每一种级别都规定了一个事务中所做的修改
InnoDB支持所有隔离级别
	set transaction isolation level 级别
1.read uncommitted(未提交读)
	事务中的修改即使没有提交,对其他事务也都是可见的,事务可以读取未提交的数据,这一现象也称之为"脏读"
2.read committed(提交读)
	大多数数据库系统默认的隔离级别
  一个事务从开始直到提交之前所作的任何修改对其他事务都是不可见的,这种级别也叫做"不可重复读"
3.repeatable read(可重复读)		# MySQL默认隔离级别
	能够解决"脏读"问题,但是无法解决"幻读"
  所谓幻读指的是当某个事务在读取某个范围内的记录时另外一个事务又在该范围内插入了新的记录,当之前的事务再次读取该范围的记录会产生幻行,InnoDB和XtraDB通过多版本并发控制(MVCC)及间隙锁策略解决该问题
4.serializable(可串行读)
	强制事务串行执行,很少使用该级别
    
    
MVCC只能在read committed(提交读)、repeatable read(可重复读)两种隔离级别下工作,其他两个不兼容(read uncommitted:总是读取最新  serializable:所有的行都加锁)

InnoDB的MVCC通过在每行记录后面保存两个隐藏的列来实现MVCC
	一个列保存了行的创建时间
  一个列保存了行的过期时间(或删除时间)  # 本质是系统版本号
每开始一个新的事务版本号都会自动递增,事务开始时刻的系统版本号会作为事务的版本号用来和查询到的每行记录版本号进行比较

例如
刚插入第一条数据的时候,我们默认事务id为1,实际是这样存储的
    username		create_version		delete_version
    jason						1					
可以看到,我们在content列插入了kobe这条数据,在create_version这列存储了1,1是这次插入操作的事务id。
然后我们将jason修改为jason01,实际存储是这样的
    username		create_version		delete_version
    jason						1									2
    jason01					2
可以看到,update的时候,会先将之前的数据delete_version标记为当前新的事务id,也就是2,然后将新数据写入,将新数据的create_version标记为新的事务id
当我们删除数据的时候,实际存储是这样的
		username		create_version		delete_version
    jason01					2									 3
"""
由此当我们查询一条记录的时候,只有满足以下两个条件的记录才会被显示出来:
   1.当前事务id要大于或者等于当前行的create_version值,这表示在事务开始前这行数据已经存在了。
   2.当前事务id要小于delete_version值,这表示在事务开始之后这行记录才被删除。
"""

存储过程

可以看成是python中的自定义函数

# 无参函数
delimiter $$
create procedure p1()
begin
	select * from cmd;
end $$
delimiter ;

# 调用
call p1()


# 有参函数
delimiter $$
create procedure p2(
    in m int,  # in表示这个参数必须只能是传入不能被返回出去
    in n int,  
    out res int  # out表示这个参数可以被返回出去,还有一个inout表示即可以传入也可以被返回出去
)
begin
    select * from cmd where id > m and id < n;
    set res=0;  # 用来标志存储过程是否执行
end $$
delimiter ;

# 针对res需要先提前定义
set @res=10;  定义
select @res;  查看
call p1(1,5,@res)  调用
select @res  查看

"""
查看存储过程具体信息
	show create procedure pro1;
查看所有存储过程
	show procedure status;
删除存储过程
	drop procedure pro1;
"""

# 大前提:存储过程在哪个库下面创建的只能在对应的库下面才能使用!!!

# 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;')

函数

可以看成是python中的内置函数

"ps:可以通过help 函数名    查看帮助信息!"
# 1.移除指定字符
Trim、LTrim、RTrim

# 2.大小写转换
Lower、Upper

# 3.获取左右起始指定个数字符
Left、Right

# 4.返回读音相似值(对英文效果)
Soundex
"""
eg:客户表中有一个顾客登记的用户名为J.Lee
		但如果这是输入错误真名其实叫J.Lie,可以使用soundex匹配发音类似的
		where Soundex(name)=Soundex('J.Lie')
"""

# 5.日期格式:date_format
'''在MySQL中表示时间格式尽量采用2022-11-11形式'''
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');

1.where Date(sub_time) = '2015-03-01'
2.where Year(sub_time)=2016 AND Month(sub_time)=07;
# 更多日期处理相关函数 
	adddate	增加一个日期 
	addtime	增加一个时间
	datediff计算两个日期差值

流程控制

# 分支结构
declare i int default 0;
IF i = 1 THEN
	SELECT 1;
ELSEIF i = 2 THEN
	SELECT 2;
ELSE
	SELECT 7;
END IF;

# 循环结构
DECLARE num INT ;
SET num = 0 ;
WHILE num < 10 DO
	SELECT num ;
	SET num = num + 1 ;
END WHILE ;

索引相关概念

1)索引就好比一本书的目录,它能让你更快的找到自己想要的内容
2)让获取的数据更有目的性,从而提高数据库检索数据的性能

索引在MySQL中也叫做“键”,是存储引擎用于快速找到记录的一种数据结构
	* primary key
	* unique key
	* index key
1.上述的三个key都可以加快数据查询
2.primary key和unique key除了可以加快查询本身还自带限制条件而index key很单一就是用来加快数据查询
3.外键不属于索引键的范围 是用来建立关系的 与加快查询无关

索引加快查询的本质
	id int primary key auto_increment,
 	name varchar(32) unique,
  	province varchar(32)
 	age int
 	phone bigint
 	
	select name from userinfo where phone=18818888888;  # 一页页的翻
	select name from userinfo where id=99999;  # 按照目录确定页数找

索引可以加快数据查询 但是会降低增删的速度
通常情况下我们频繁使用某些字段查询数据
	为了提升查询的速度可以将该字段建立索引
    
聚集索引(primary key)
	主键、主键索引
辅助索引(unique,index)
	除主键意外的都是辅助索引
覆盖索引
	select name from user where name='jason';
非覆盖索引
	select age from user where name='jason';

作业

1.课下自行百度学习什么是数据库三大范式
2.整理今日内容及博客

标签:事务,name,python,查询,---,四十四,where,id,select
From: https://www.cnblogs.com/tengyifan888/p/16936673.html

相关文章

  • KCTF-病疫先兆
    一道爆破题,我不理解为什么不把这题放在第二个ida打开先对输入做了分割,分成了三部分看到下面对中间部分做了校验,得到第一部分KCTF剩下两部分都用到了随机数,随机数的种......
  • 计算机网络详解(基础篇)1-3章(韩立刚老师)
    1.lnternet发展网络:让部分电脑实现短距通信(较小范围:如实验室)互联网:路由器连接多个网络形成互联网,实现远距通信。(任意部门或单位或个体都可接入)通讯介质可以是光纤或无......
  • Response-输出字符数据、输出字节数据
    Response-输出字符数据服务器输出字符数据到浏览器步骤:1.获取字符输出流2.输出数据注意:乱码问题......
  • Codeforces Round #836 (Div. 2) A-D题解
    比赛链接A、SSeeeeiinnggDDoouubbllee一个字符串的每个字母翻倍,且没有其他限制。所以把字符串正着输一遍,再倒叙输出一遍即可。点击查看代码#include<bits/stdc++.h>......
  • C#数据结构-List实现
    把C#内部的List<T>手动实现了一遍,实现很多Array开头的方法,比如Array.Copy(),Array.Clear()等,在.NETFramework的内部方法,当然C#内部实现应该更快。同时,拷贝了C#的排序源码......
  • C#--异步回调
     异步回调:主线程在执行的时候,打开一个子线程,主线程继续执行,当子线程执行完成的时候,主线程立即输出主线程的运行结果,主线程继续执行。注意:1.调用BeginInvoke开始异步加载,在......
  • Unity--Cinemachine官方实例详解
    1.2DCamera搭建一个快速场景,MainCamera选择Orthographic。在Cinemachine下有Create2DCamera,在生成的相机中设置follow,同时注意body的设置,如下图所示在虚拟相机中还需要......
  • C#--序列化和反序列化
    序列化是指将对象转换成字节流,从而存储对象或将对象传输到内存、数据库或文件的过程。它的主要用途是保存对象的状态,以便能够在需要时重新创建对象。反向过程称为“反序列......
  • C#--泛型委托Action<T>、Func<T>、Predicate<T>的解析和用法
    C#中的委托(Delegate)类似于C或C++中函数的指针。委托是保存对某个方法引用的一种引用类型变量。若要引用的方法,具有两个参数没有返回值,使用Action<T1, T2>委托,则不需要......
  • Unity Animator -- Apply Root Motion
    Animator.ApplyRootMotion这个属性是用来控制物体在播放骨骼动画的时候是否应用骨骼根节点的运动参数。一、当没有骨骼根节点的情况时,比如只是一个Cube立方体,如果勾选了Appl......