第三十七章 MYSQL(二)
MYSQL注入问题:
1、写sql语句的时候, %传值的时候, 需要加引号:
sql = "select * from t4 where name = '%s' and pwd = '%s'" % (username, pwd)
上面的sql语句带来的风险是:
例一:
username = zekai' #
select * from t4 where name = 'zekai' #' and pwd = ''
例二:
username = dbsahvbdsha' or 1=1 #
select * from t4 where name = 'dbsahvbdsha' or 1=1
上面出现的问题,我们称之为 SQL注入 (**********************************)
2、出现问题的根源是:
因为太过于相信用户的输入, 导致我们在接受用户输入的参数的时候, 并没有对他进行转义
解决SQL注入:
1. 自己手工对用户输入的值进行转义
2. 使用execute()自动进行过滤
sql = "select * from t4 where name = %s and pwd = %s"
cursor.execute(sql,(username, pwd))
插入一条
cursor.execute(sql, ('lxxx', '1234'))
插入多条
data = [('aaaaa', 'aaa'),('bbbb', 'bbb'),('ffff', '666'),('rrrr', '888')]
cursor.executemany(sql, data)
try:
cursor.execute(sql, ('lxxx', '1234'))
删除和更新的时候, 需要事物提交
conn.commit()
except Exception as e:
conn.rollback()
cursor.lastrowid : 最后一行的行数
事务: (****)
特性:(ACID)
原子性(Atomicity): 一组操作, 要么都成功, 要么都失败
一致性(Consistency):指事务发生前和发生后,数据的总额依然匹配
隔离性(Isolation):简单点说,某个事务的操作对其他事务不可见的
持久性(Durability):当事务完成后,其影响应该保留下来,不能撤消,只能通过“另开起一个事物”来抵消之前的错误
场景:
思考:
我去银行给朋友汇款,
我卡上有1000元,
朋友卡上500元,
我给朋友转账100元(无手续费),
如果,网线断了, 我的钱刚扣,而朋友的钱又没加时, 怎么办?
create table t11 (
id int auto_increment primary key,
name varchar(32) not null default '',
money int not null default 0
)engine=Innodb charset=utf8;
insert into t11 (name,money) values ('zekai', 1000), ('eagon', 500);
解决方法:
开启事务 (start transaction)
(执行sql操作)
commit : 提交上面的SQL, 让其生效
rollback: 回滚
show full tables; 显示全部类型
存储引擎:(三种engine)
create table t1(
id int auto_increment primary key,
name varchar(32) not null default ''
)engine=Innodb charset=utf8;
分类: (******)
1、Innodb
1.(默认版本包含5.5)
2.支持事务
3.不支持全文索引
4.索引和数据都是在同一个文件中, .ibd
表的结构实在.frm文件中
2、MyIsam
1.(默认版本5.5以下 5.3)
2.不支持事务
3.支持全文索引
4..frm: 表结构
.MYD: 表数据
.MYI: 表索引
3、memory:
索引:
全文索引:sphinx
作用: 加快查询的速度
类比: 新华字典的目录, 可以将索引理解成一个特殊的文件, 然后如果没有这个文件的话, 查询是从前到后查找数据的,
如果有这个文件的话, 会按照一种特殊的数据结构(二叉树)查找数据
分类:
主键索引: 加快查询 + 不能重复 + 不能为空 primary key
唯一索引: 加快查询 + 不能重复 unique(列名)
联合唯一索引: 加快查询 + 不能重复 unique(列名1,列名2)
普通索引: 加快查询 index('列名')
创建:
主键索引:
第一种:
create table t1(
id int auto_increment primary key,
name varchar(32) not null default ''
)engine=Innodb charset=utf8;
第二种:
alter table t1 change id id int auto_increment primary key;
唯一索引:
第一种:
create table t1(
id int auto_increment primary key,
name varchar(32) not null default '',
unique ix_name ('name')
)engine=Innodb charset=utf8;
第二种:
create unique index 索引名称(ix_name) on 表名(t1)(name);
create unique index 索引名称(ix_name_age) on 表名(t1)(name,age);
普通索引:
第一种:
create table t1(
id int auto_increment primary key,
name varchar(32) not null default '',
index ix_name ('name')
)engine=Innodb charset=utf8;
第二种:
create index 索引名称(ix_name) on 表名(t1)(name);
删除:
drop index 索引名称(ix_name) on 表名(t1);
场景:
使用频繁的列上加一个索引
索引的缺点:
版本5.3以下:
删除和修改的速度就变慢了
版本5.5以上:
删除和修改的速度不是特别的慢
create table t12(
id int auto_increment primary key,
name varchar(32) not null default '',
email varchar(32) not null default ''
) engine=Innodb charset=utf8;
索引的使用:
explain 工具
查看sql语句是否用的上索引, 或者查看sql执行效率的工具
给执行的SQL语句出一个报告, 通过此报告来判断sql语句的执行效率和效果
ES (elasticsearch )
SQL语句的规则:
- 不建议使用 like 进行搜索
- 组合索引最左前缀
如果组合索引为:(name,email)
where name and email -- 使用索引
where name -- 使用索引
where email -- 不使用索引
权限管理:
创建用户
create user '用户名'@'IP地址' identified by '密码';
creaee user 'zekai'@'192.168.1.123' identified by '123qwe';
creaee user 'zekai'@'192.168.1.%' identified by '123qwe';
create user 'zekai'@'%' identified by '123qwe';
删除用户
drop user '用户名'@'IP地址';
修改用户
rename user '用户名'@'IP地址' to '新用户名'@'IP地址';
修改密码
set password for '用户名'@'IP地址' = Password('新密码')
授权:
grant 权限 on 数据库.表 to '用户'@'IP地址' -- 授权
grant select on db1.* to 'zekai'@'%';
grant select on *.* to 'zekai'@'%';
grant select, insert, delete on db1.* to 'zekai'@'%';
记住:
flush privileges;