一、Navicat 可视化工具的使用
1、Navicat [1] 是一套快速、可靠并价格相宜的数据库管理工具,专为简化数据库的管理及降低系统管理成本而设。
它的设计符合数据库管理员、开发人员及中小企业的需要。Navicat 是以直觉化的图形用户界面而建的,
让你可以以安全并且简单的方式创建、组织、访问并共用信息。
#要求掌握 1;测试+连接数据库 2:新建库 3:新建表,新增字段+类型+约束条件的创建 4:设计表:外键 5:新建查询 6:建立表的模型 7:转储/运行SQL文件 8:通过模型多表之间查询,输入命令
#注意
批量加注释:ctrl+?建
批量去注释:CTRL+shift+?建
2、 软件操作界面及使用注意事项:
3、新建库时注意事项:
4、可以把建好的表转储为SQL文件保存下来,可以把新的SQL文件直接添加并运行(可以直接利用别人建好的框架模型或数据)
二、练习题:(多表之间的查询)
1、查询所有的课程的名称以及对应的任课老师姓名 4、查询平均成绩大于八十分的同学的姓名和平均成绩 7、 查询没有报李平老师课的学生姓名 8、 查询没有同时选修物理课程和体育课程的学生姓名 9、 查询挂科超过两门(包括两门)的学生姓名和班级 # 解题步骤: 把复杂的问题拆分,按条件拆分一步一的写,再基于上一次查询的结果再做条件筛选
1:查询所有的课程的名称以及对应的任课老师姓名
解题思路:(1):先采用连表操作 inner join(内连接把老师和课程的信息查找)
select *from course inner join teacher on course.teacher_id =teacher.tid; 内连接查找
(2):在找到老师和课程的基础上,再查找课程对应的老师信息
把 * 换成要查找的内容即可:
SELECT
course.cname,
teacher.tname
FROM
course
INNER JOIN teacher ON course.teacher_id = teacher.tid;
2:查询平均成绩大于八十分的同学的姓名和平均成绩
'''SELECT student.sname, t1.avg_num FROM student # 第二步:查询学生符合符合条件的学生 再用avg INNER JOIN ( SELECT student_id, avg(num) AS avg_num FROM score # 第一步:先查找平均成绩大于80分的同学 GROUP BY student_id HAVING # 分组后的条件筛选 avg(num) > 80 ) AS t1 ON student.sid = t1.student_id;'''
3: 查询没有报李平老师课的学生姓名(找出报名李平老师课程的学生,然后取反就可以)
SELECT student.sname FROM student WHERE sid NOT IN ( SELECT DISTINCT student_id FROM score WHERE course_id IN ( SELECT course.cid FROM course INNER JOIN teacher ON course.teacher_id = teacher.tid WHERE teacher.tname = '李平老师' ) );
4、 查询没有同时选修物理课程和体育课程的学生姓名(没有同时选修指的是选修了一门的,
思路是得到物理+体育课程的学生信息表,然后基于学生分组,统计count(课程)=1)
SELECT student.sname FROM student WHERE sid IN ( SELECT student_id FROM score WHERE course_id IN ( SELECT cid FROM course WHERE cname = '物理' OR cname = '体育' ) GROUP BY student_id HAVING COUNT(course_id) = 1 );
5、查询挂科超过两门(包括两门)的学生姓名和班级
select student.sname,class.caption from class INNER JOIN student on class.cid = student.class_id WHERE student.sid in (select student_id from score where num < 60 GROUP BY student_id HAVING COUNT(course_id) >=2)
三、pymysql 模块
命令行安装: pip insatll mysql 用Python来实现操作mysql
import pymysql conn = pymysql.connect( host = '127.0.0.1', port = 3306, user = 'root', password = '123', database = 'day38', charset = 'utf8' # 编码千万不要加- 如果写成了utf-8会直接报错 ) # 向mysqld服务端发送请求连接 cursor = conn.cursor(pymysql.cursors.DictCursor) # 产生一个游标对象 以字典的形式返回查询出来的数据 # 键是表的字段 值是表的字段对应的信息 sql = 'select * from teacher' cursor.execute(sql) # 执行传入的sql语句 print(cursor.fetchone()) # 只获取一条数据 print(cursor.fetchone()) # 只获取一条数据 # cursor.scroll(2,'absolute') # 控制光标移动 absolute相对于其实位置 往后移动几位 cursor.scroll(1,'relative') # relative相对于当前位置 往后移动几位 print(cursor.fetchall()) # 获取所有的数据 返回的结果是一个列表
四、mysql 注入问题
解决在输入没有密码或者用户名错误的情况下也能访问数据的问题。
# 2.代码链接 import pymysql #链接 conn=pymysql.connect( host='localhost', user='root', password='123', database='egon', charset='utf8') #游标 cursor=conn.cursor() #执行完毕返回的结果集默认以元组显示 #cursor=conn.cursor(cursor=pymysql.cursors.DictCursor) # 以字典的方式显示数据 # 3.pymysql操作数据库 #执行sql语句 user = input(">>>:").strip() pwd = input(">>>:").strip() sql='select * from userinfo where name="%s" and password="%s"' %(user,pwd) #注意%s需要加引号 rows=cursor.execute(sql) #执行sql语句,返回sql查询成功的记录数目 # 获取真实数据cursor.fetchone(),cursor.fetchall(),cursor.fetchmany(),类似管道取值,获取一条,所有,多条 cursor.scroll(1,'relative') # 相对移动 cursor.scroll(3,'absolute') # 绝对移动 cursor.close() conn.close()
sql注入的问题:
通过修改验证方式,解决在没有输入正确的用户名和密码时也能获取数据的情况
import pymysql conn = pymysql.connect( host = '127.0.0.1', port = 3306, user = 'root', password = '123', database = 'day38', charset = 'utf8' # 编码千万不要加- 如果写成了utf-8会直接报错 ) cursor = conn.cursor(pymysql.cursors.DictCursor) username =input('username>>>:').strip() password = input('password>>>:').strip() sql ="select * from userinfo where name = %s and password = %s" print(sql) res = cursor.execute(sql,(username,password)) # execute 会自动识别sql语句中的%s 帮你做替换 if res: print(cursor.fetchall()) else: print("用户名和密码错误!")
结果:
username>>>:james
password>>>:123
select * from userinfo where name = %s and password = %s
[{'id': 2, 'name': 'james', 'password': '123'}]
""" sql注入 就是利用注释等具有特殊意义的符号 来完成一些骚操作
后续写sql语句 不要手动拼接关键性的数据 而是让excute帮你去做拼接 """
sql ="select * from userinfo where name = %s and password = %s" %(username,password)
res = cursor.execute(sql)
如果这么写的话会出现注入问题:利用mysql -- 注释的语法实现破解密码 如输入:Jack‘-- bhgdj 或 xxx' or 1=1 没有密码不知道用户名也能获取数据
五、
import pymysql conn = pymysql.connect( host = '127.0.0.1', port = 3306, user = 'root', password = '123', database = 'day38', charset = 'utf8', # 编码千万不要加- 如果写成了utf-8会直接报错 autocommit = True # 这个参数配置完成后 增删改操作都不需要在手动加conn.commit了 ) cursor = conn.cursor(pymysql.cursors.DictCursor) sql = 'insert into userinfo (name,password) values("jerry","666")' # sql = 'update userinfo set name = "jasonhs" where id = 1' # sql = 'delete from userinfo where id = 2' cursor.execute(sql) # conn.commit()
""" 增删改操作 都必须加一句 conn.commit()操作 """