!这是dba的活儿!,可是万一公司没有dba?python
mysql用户指的是什么?mysql
咱们每一次在操做前都须要指定帐号和密码,这个帐号就是mysql的用户;sql
为何要管理?数据库
一个公司不可能只有一个工程师,大公司,不不只有不少工程师 还有不少不一样部门,可是数据库服务器只有一个,你们都要访问,这就涉及到用户和权限问题了服务器
一个工程师对应一个帐户,微信
哪些工程师能够操做哪些数据库,哪些表,甚至哪些字段,均可以进行控制,例如,腾讯,有qq和微信不一样项目,qq的工程师,就不该该去访问微信项目的数据;ide
mysql本质上是一款cs软件,它具有用户认证!函数
咱们有没有作过用户认证呢? ATM! 购物车,都作过,fetch
咱们是如何实现的?写入文件,mysql也是同样的,code
只不过它把文件称为表
那么要怎么添加帐户呢?
把用户信息写入表中就能够了
来看看它都把数据放在哪一个表中了!
自带的mysql数据库,四个表用于存储帐户信息以及权限 user db table_priv columns_priv
user->db->table_priv->columns_priv
select *from user; #因为字段较多 以表格形式展现 会比较乱,能够添加\G来纵向显示 select *from user\G;
内置root帐户字段信息解析
create user 用户名@"ip地址" "identified" by 密码; create user tom@"192.168.101" identified by "123";
该语句表面tom只能在101机器上使用,别的机器就没法登陆
用%能够表示在任意机器可用
注意:该方式建立的帐号没有任何权限 因此了解便可
受权:
受权语句执行时若是帐号不存在会自动建立帐号 因此更推荐使用
注意:默认只有root才能为其余帐号受权
grant all on *.* to tom@"localhost" identified by "123"; #该语句中的all 增删改查全部权限 可是不包括grant权限 #*.* 表示任何数据库 任何表 存储在user表 grant all on *.* to toms@"%" identified by "123"; # host 为% 表示 该帐户能够在任何主机上登陆可是不包括localhost grant all on *.* to toms@"localhost" identified by "123"; # 继续执行 上述语句保证localhost也能够登陆该帐户 grant all on db.* to tom@"localhost" identified by "123" #db.* 该用户能够操做db数据库的任何表 存储在 db表 grant all on db.t1 to tom@"localhost" identified by "123" #db.* 该用户能够操做db数据库的t1表 存储在 table_privi表 grant select(id) on db.t1 to tom@"localhost" identified by "123" #精确到字段 和 操做级别 #该用户只能查询 db下的t1表 grant all on *.* to tom@"localhost" identified by "123" with grant option; #with grant option 表示该帐户能够将权限授予其余用户 REVOKE all privileges [column] on db.table from user@"host"; #收回权限 drop user@"host" #删除用户 flush privileges; #刷新权限表 一些时候权限信息可能会有所延迟 能够执行该语句当即刷新权限信息
pymysql是python提供的一个mysql客户端模块,用于与mysql服务器创建链接,发送查询,并获取结果等;
import pymysql # 1.创建链接 try: conn = pymysql.connect(host="127.0.0.1",port=3306,user="root",password="",db="day46",) print("链接服务器成功!") #2.获取游标对象 cursor = conn.cursor() #3.执行sql语句 count = cursor.execute("select *from user") print("结果数量: %s" % count) # 提取结果 # print(cursor.fetchall()) # print(cursor.fetchone()) # print(cursor.fetchmany(1)) # 移动游标位置 相对当前位置 cursor.scroll(1,"relative") cursor.scroll(-1, "relative") print(cursor.fetchone()) # 移动游标位置 使用绝对位置 cursor.scroll(0, "absolute") print(cursor.fetchone()) print(cursor.fetchall()) # 注意 游标移动到末尾后没法在读取到数据 若需重复读取数据,须要使用scroll来移动游标 except Exception as e: print("链接服务器失败.....") print(type(e),e) finally: if cursor: cursor.close() print("关闭游标") if conn: conn.close() print("关闭连接")
上述代码中 fetch 相关函数返回值类型为元组,使用起来不够方便,咱们能够在建立游标时指定游标类型为字典类型像这样:
cursor = conn.cursor(pymysql.cursors.DictCursor)
何为sql注入
sql注入指的是,用户在输入数据时,按照sql的语法,来编写带有攻击目的的sql语句,并插入到原始语句中执行.
例如:登陆功能,须要用户输入用户名和密码
正常的一个登陆功能代码以下:
try: conn = pymysql.connect(host="127.0.0.1",port=3306,user="root",password="",db="day46",) print("链接服务器成功!") cursor = conn.cursor(pymysql.cursors.DictCursor) user = input("username:") password = input("password:") count = cursor.execute("select *from user where name = '%s' and password = '%s'" % (user,password)) if count: print("登陆成功!") else: print("登陆失败!") except Exception as e: print(type(e),e) finally: if cursor:cursor.close() if conn: conn.close()
上述代码有被注入攻击的危险
尝试在用户名中输入如下内容,密码随意 jerry' — ass 或者连用户名都不用写 ' or 1 = 1 -- asaa
1.客户端在发送sql给服务器前进行re判断
这样的问题在于一些程序能够模拟客户端直接发送请求给服务器
2.在服务器端将sql交给mysql是做进一步处理,相关的代码其实pymysql已经作了封装
咱们只要保证不要本身来拼接sql语句便可,将拼接参数操做交给pymysql.
try: conn = pymysql.connect(host="127.0.0.1",port=3306,user="root",password="",db="day46",) print("链接服务器成功!") cursor = conn.cursor(pymysql.cursors.DictCursor) user = input("username:") password = input("password:") sql = "select *from user where name = %s and password = %s" print(sql) count = cursor.execute(sql,(user,password)) # 参数交给模块 if count: print("登陆成功!") else: print("登陆失败!") except Exception as e: print(type(e),e) finally: if cursor:cursor.close() if conn: conn.close()
import pymysql # 1.创建链接 try: conn = pymysql.connect(host="127.0.0.1",port=3306,user="root",password="",db="day46",) print("链接服务器成功!") cursor = conn.cursor(pymysql.cursors.DictCursor) #增 #sql = "insert into user values(null,%s,%s,%s)" #count = cursor.execute(sql,("tom","man","123321")) # 一次性插入多条记录 #sql = "insert into user values (null,%s,%s,%s)" #count = cursor.executemany(sql, [("周芷若","woman","123"), ("赵敏","woman","321")]) #删 # count = cursor.execute("delete from user where id = 1") #改 count = cursor.execute("update user set name = '刘大炮' where id = 1") if count: print("执行成功!") else: print("执行失败!") # 获取最新的id # print(cursor.lastrowid) except Exception as e: print(type(e),e) finally: if cursor:cursor.close() if conn: conn.close()
强调:pymysql 对于数据的增删改默认都不会生效,必须调用连接对象的commit()来提交修改 或者在建立连接对象时指定为自动提交;
conn.commit() #或者建立连接对象时指定为自动提交 conn = pymysql.connect(host="127.0.0.1",port=3306,user="root",password="",db="day46",autocommit=True)