Day 42 数据库高级2
数据库高级
用户管理
为了控制权限,让不同开发者仅能操作属于自己的业务范围内的数据
创建mysql账户
创建张数的三个数据
账户 密码 id地址
ip是用于限制某个账户只能在那些机器上登录
#创建用户
create user 用户名@主机地址 identified by '密码';
#创建用户的操作只能用root账户来进行,其他用root账户创建的账号即使有全部的权限也没法创建账户
#删除用户 同时将删除所有的权限
drop user 用户名@主机地址;
权限管理
涉及到的表
user 与用户相关信息
db 用户的数据库权限信息
tables_priv 用户的表权限
columns_priv 用户的字段权限
语法
#若果用户不存在则自动创建新用户
grant all on *.* to 用户名@主机地址 identified by '密码';
#all表示是所有的字段,第一个*是库名,第二个*是表名,如果需要设置用户可以在任何主机上登录,主机地址可以用%来表示
#收回权限
revoke all on *.* from 用户名@主机地址;
#刷新权限
flush privileges;
#with grant option 表示可以将当前登录用户拥有的权限授予其他的用户
grant all on *.* to root1@localhost identified by '123' with grant option;
可视化客户端
navicat
pymysql
pymsql是一个第三方模块,帮我们封装了建立链接,用户认证,sql的执行以及结果的获取
#导入模块
import pymysql
#连接数据库服务器,获取连接对象(本质上就是封装好的socket)
conn = pymysql.connect(
host='127.0.0.1',
port=3306,
user='root',
password='',
database='school'
)
#通过连接拿到游标对象
#默认的游标对象是元祖类型,不方便使用,需要更换为字典类型的游标
c=conn.cursor(pymysql.cursors.DictCursor)
#游标对象就是执行sql语句返回的结果信息
#执行sql语句
sql ='select * from table_name'
res=c.execute(sql)
#res是执行sql语句得到结果条数,如果为空则表示执行不成功
#获取结果
print(c.fetchall()) #获取全部结果
print(c.fetchmay(n)) #获取指定n条结果
print(c.fetchone()) #获取一条结果
print(c.fetchone()) #获取下一条结果
#关闭链接
c.close()
conn.close()
#移动光标,第一个参数是需要移动位置的个数,mode指定相对或绝对
c.scroll(1,mode='absolute')
sql注入攻击
sql注入攻击指的是在输入数据的时候,按照sql的语法规范,提交了用于攻击性目的的数据
在服务器端执行sql之前做sql的验证以避免sql注入攻击
pymysql已经封装了验证操作,我们只需要将参数交给pymysql来拼接即可
示例:用户注册
import pymysql
conn = pymysql.connect(
host='127.0.0.1',
port=3306,
user='root',
password='',
database='school',
autocommit=False #自动提交 默认不开启,应该手动确认提交的时间
)
c=conn.cursor(pymysql.cursors.DictCursor)
name=input('username:')
gender=input('gender:')
class_id=input('choice class:')
sql1 ='select * from student where sname =%s'
sql2 ='insert into student (sname,gender,class_id) values(%s,%s,%s)'
if c.execute(sql1,(name,)): #此处就是sql验证,参数交由pymysql进行拼接
print('用户已存在')
else:
if c.execute(sql2,(name,gender,class_id)):
print('注册成功')
conn.commit() #提交函数
else:
print('注册失败')
c.close()
conn.close()
# mysql会自动开启事物,需要在合适的位置手动提交
调用存储过程
# 创建名为add的存储过程
delimiter |
create procedure add1(in a int ,in b int , out c int)
begin
set c=a+b;
end|
delimiter ;
#pymysql中调用
import pymysql
conn = pymysql.connect(
host = "127.0.0.1", #如果是本机 可以忽略
port = 3306, # 如果没改过 可以忽略
user = "root", #必填
password = "", #必填
database = "day42", #必填,
autocommit=True # 开启自动提交 不常用....
)
c = conn.cursor(pymysql.cursors.DictCursor)
c.callproc("add1",(1,2,1212)) # @_add1_0 @_add1_1 @_add1_2
c.execute("select @_add1_2")
print(c.fetchone())
# 调用存储过程时,传入参数会自动定义成变量
# 命名方式 @_过程的名称_参数的索引 ,从0开始