• day48-数据库-navicat使用、python操作数据库、sql注入


    每日测验

    • MySQL中常用查询关键字及作用
    • 针对多表查询有哪些查询方式,各自有什么特点

    昨日内容回顾

    • 查询主要关键字

      select distinct 字段1,字段2,... from 表名
      	where 分组之前的筛选条件
          group by  分组条件
          having  分组之后的筛选条件
          order by  排序字段1 asc,排序字段2 desc
          limit 5,5
      
    • where

      where id>=3 and id<=6;
      where id between 3 and 6;
      
      where salary=18000 or salary=17000;
      where salary in (18000,17000);
      where salary not in (18000,17000);
      
      where salary*20 from emp;
      
      # 模糊匹配 like
        %  任意多个字符
      _  任意单个字符
        where name like '%mode%';
      where name like '____';
      where char_length(name) = 4;
      
      # 针对null数据 判断的时候用is不要用=
      where post_comment is null;
      
    • group by

      # 分组的应用场景非常多 
      	每个
          平均
          最大
          最小
          ...
        分组之后只能直接获取到分组的依据 其他字段都无法直接获取
      set global sql_mode = 'only_full_group_by'
        select * from emp group by post;  报错
      select post from emp group by post;
      
      # group_concat:帮助我们获取到分组之外的字段信息并且可以拼接多个字段
      select post,group_concat(salary,':',name) from emp;
      # concat:分组之前帮助我们获取字段信息并且可以拼接多个字段
      select concat(name,'??') from emp;
      # concat_ws:如果多个字段之间的连接符号是相同的情况下 你可以直接使用concat_ws来完成
      select concat_ws(':',name,age,sex) from emp;
        复习
      '?'.join([111,222,333,444])  报错!
        
      # as语法
      	1 可以给展示字段起别名
      	2 可以给表起别名
      
      # 聚合函数
      	max
          min
          sum
          count
          avg
        聚合函数必须在分组之后使用
      
    • having

      # 用法根where一模一样 只不过它是作用于分组之后的再次筛选
      ....group by post having avg(salary) > 30000;
      
    • distinct

      # 数据必须是一模一样的情况下才能去重 
      select distinct post from emp;
      
    • order by

      # 排序 默认是升序
      order by salary;  ===   order by salary asc;
      order by salary desc;
      
      order by salary asc,age desc;  # 还支持多个字段备用比较
      
    • limit

        限制数据的展示条数    效果就是分页的效果
        select * from emp limit 5;
      
      limit 5;
      limit 5,5  第一个参数是起始位置 第二个参数是条数
      
    • regexp

        正则是一门独立的语言
      在sql中如果你想使用正则需要借助于re模块
      	面试题
      		1.re模块中常用的方法
      			findall:分组优先展示
      				^j.*(n|y)$
      				不会展示所有正则表达式匹配到的内容
      				而仅仅展示括号内正则表达式匹配到的内容
      			match:从头匹配
      			search:从整体匹配
      		2.贪婪匹配与非贪婪匹配
      			正则表达式默认都是贪婪匹配的
      			将贪婪变成非贪婪只需要在正则表达式后面加?
      			.*  贪婪
      			.*? 非贪婪
        select * from emp where name regexp '^j.*n$'
      
    • 多表查询

      # 联表操作
      select * from emp,dep;  笛卡尔积
      	inner join
          	只拼接两种表中都公有的部分
              select * from emp inner join dep 
              	on emp.dep_id = dep.id;
                  # 要加上表的前缀 不然容易造成冲突 
          left join
          	左表数据全部展示  没有对应的就用NULL补全
          right join
          	右表数据全部展示  没有对应的就用NULL补全	
          union
          	左右全书展示 没有对应的就用NULL补全	
      # 子查询
        子查询就是我们平时解决问题的思路 分步处理
      将一张表的查询结果当做另外一条sql语句的查询条件
      (当做条件的时候 用括号括起来)
      select * from emp where id in (select id from dep);
      
    • 总结

      # 书写sql语句的时候 select后面先用*占位 之后写完再改
      # 在写较为复杂的sql语句的时候 不要想着一口气写完 写一点查一点看一点再写!!!(只要是涉及到数据查询相关的语法都不应该一次性写完 不太现实)
      # 在做多表查询的时候 联表操作和子查询可能会结合使用
      

    知识点补充

    # 查询平均年龄在25岁以上的部门名称
    """只要是多表查询 就有两种思路    联表    子查询# 联表操作
    	1 先拿到部门和员工表 拼接之后的结果
    	2 分析语义 得出需要进行分组
        select dep.name from emp inner join dep
        	on emp.dep_id = dep.id
            group by dep.name
            having avg(age) > 25
            ;
    	"""涉及到多表操作的时候 一定要加上表的前缀# 子查询
    	select name from dep where id in
    		(select dep_id from emp group by dep_id 
        		having avg(age) > 25);
    
    # 关键字exists(了解)
    	只返回布尔值 True False
        返回True的时候外层查询语句执行
        返回False的时候外层查询语句不再执行
    	select * from emp where exists 
        	(select id from dep where id>3);
            
            
       select * from emp where exists 
        	(select id from dep where id>300);
    

    今日内容概要

    • navicat可视化界面操作数据库
    • 数据库查询题目讲解(多表操作)
    • python如何操作MySQL(pymysql模块)
    • sql注入问题
    • pymysql模块增删改查数据操作

    今日内容详细

    Navicat软件

    安装

    直接百度搜索 有破解版的也有非破解
    非破解的有试用期 你如果不嫌麻烦 你就用使用
    到期之后重新装再使用 或者破解一下也很简单
    https://www.cr173.com/soft/126934.html
        
    下载完成后是一个压缩包 直接解压 然后点击安装 有提醒直接点击next即可
    
    navicat能够充当多个数据库的客户端
    
    navicat图形化界面有时候反应速度较慢 你可以选择刷新或者关闭当前窗口再次打开即可
    
    当你有一些需求该软件无法满足的时候 你就自己动手写sql
    
    

    提示

    1 MySQL是不区分大小写的
    	验证码忽略大小写
    		内部统一转大写或者小写比较即可
    			upper
    			lower
    
    2 MySQL建议所有的关键字写大写
    
    3 MySQL中的注释 有两种
    	--
    	#
    
    4 在navicat中如何快速的注释和解注释
    	ctrl + ?  加注释
    	ctrl + ?  基于上述操作再来一次就是解开注释
    	如果你的navicat版本不一致还有可能是
    	ctrl + shift + ?解开注释
    

    练习题

    课下一定要把握上课将的这几道题全部自己独立的理解并写出来
    
    在解决sql查询问题的时候 不要慌
    一步一步慢慢来  最终能够东拼西凑出来就过关了!!!
    
     1、查询所有的课程的名称以及对应的任课老师姓名
     SELECT
     	course.cname,
     	teacher.tname 
     FROM
     	course
     	INNER JOIN teacher ON course.teacher_id = teacher.tid;
    
     4、查询平均成绩大于八十分的同学的姓名和平均成绩
     SELECT
     	student.sname,
     	t1.avg_num 
     FROM
     	student
     	INNER JOIN (
     	SELECT
     		score.student_id,
     		avg( num ) AS avg_num 
     	FROM
     		score
     		INNER JOIN student ON score.student_id = student.sid 
     	GROUP BY
     		score.student_id 
     	HAVING
     		AVG( num ) > 80 
     	) AS t1 ON student.sid = t1.student_id;
    
    
     7、 查询没有报李平老师课的学生姓名
    # 分步操作
    # 1 先找到李平老师教授的课程id
    # 2 再找所有报了李平老师课程的学生id
    # 3 之后去学生表里面取反 就可以获取到没有报李平老师课程的学生姓名
     SELECT
     	student.sname 
     FROM
     	student 
     WHERE
     	sid NOT IN (
     	SELECT DISTINCT
     		score.student_id 
     	FROM
     		score 
     	WHERE
     		score.course_id IN ( SELECT course.cid FROM teacher INNER JOIN course ON teacher.tid = course.teacher_id WHERE teacher.tname = '李平老师' ) 
     	);
    
     8、 查询没有同时选修物理课程和体育课程的学生姓名
         (只要选了一门的 选了两门和没有选的都不要)
    # 1 先查物理和体育课程的id
    # 2 再去获取所有选了物理和体育的学生数据
    # 3 按照学生分组 利用聚合函数count筛选出只选了一门的学生id
    # 4 依旧id获取学生姓名
     SELECT
     	student.sname 
     FROM
     	student 
     WHERE
     	student.sid IN (
     	SELECT
     		score.student_id 
     	FROM
     		score 
     	WHERE
     		score.course_id IN ( SELECT course.cid FROM course WHERE course.cname IN ( '物理', '体育' ) ) 
     	GROUP BY
     		score.student_id 
     	HAVING
     		COUNT( score.course_id ) = 1 
     	);
    
     9、 查询挂科超过两门(包括两门)的学生姓名和班级
    # 1 先筛选出所有分数小于60的数据
    # 2 按照学生分组 对数据进行计数获取大于等于2的数据
    SELECT
    	class.caption,
    	student.sname 
    FROM
    	class
    	INNER JOIN student ON class.cid = student.class_id 
    WHERE
    	student.sid IN (
    	SELECT
    		score.student_id 
    	FROM
    		score 
    	WHERE
    		score.num < 60 GROUP BY score.student_id HAVING COUNT( score.course_id ) >= 2 
    	);
    

    pymysql模块

    支持sql代码操作数据库MySQL
    pip3 install pymysql
    

    sql注入

    利用一些语法的特性 书写一些特点的语句实现固定的语法
    MySQL利用的是MySQL的注释语法
    select * from user where name='jason'  jhsadklsajdkla' and password=''
    
    select * from user where name='xxx' or 1=1  sakjdkljakldjasl' and password=''
    

    日常生活中很多软件在注册的时候都不能含有特殊符号
    因为怕你构造出特定的语句入侵数据库 不安全
    敏感的数据不要自己做拼接 交给execute帮你拼接即可
    结合数据库完成一个用户的登录功能?

    import pymysql
    
    
    conn = pymysql.connect(
        host = '127.0.0.1',
        port = 3306,
        user = 'root',
        password = '123456',
        database = 'day48',
        charset = 'utf8'  # 编码千万不要加-
    )  # 链接数据库
    cursor = conn.cursor(cursor=pymysql.cursors.DictCursor)
    
    username = input('>>>:')
    password = input('>>>:')
    sql = "select * from user where name=%s and password=%s"
    # 不要手动拼接数据 先用%s占位 之后将需要拼接的数据直接交给execute方法即可
    print(sql)
    rows = cursor.execute(sql,(username,password))  # 自动识别sql里面的%s用后面元组里面的数据替换
    if rows:
        print('登录成功')
        print(cursor.fetchall())
    else:
        print('用户名密码错误')
    

    作业布置

    1 navicat自己玩一玩
    2 练习题一定要搞懂 照着我的思路一遍遍的看敲
    3 熟悉pymysql的使用
    4 sql注入产生的原因和解决方法 了解
    5 思考:如何结合mysql实现用户的注册和登录功能?
    
  • 相关阅读:
    myfocus官方网站已经挂掉,相关下载已经从googlecode转到网盘
    [综合]visio2013安装提示找不到Office.zh_cnofficeMUI.mis officemui.xml
    技巧分享:解决Word 2010当中“分页符”造成的空白行
    房贷计算器代码2.0
    房贷计算器代码
    图解-JS普通函数跟箭头函数中this的指向问题
    完全基于net core容器的超级轻量化的Quartz,支持类似net core mvc的过滤器,附过滤器实现源码
    net下的高性能轻量化半自动orm+linq的《SqlBatis》
    轻量级ORM《sqlcommon》第一个版本发布了!!!
    从0开始编写dapper核心功能、压榨性能、自己动手丰衣足食
  • 原文地址:https://www.cnblogs.com/zdw20191029/p/14553322.html
Copyright © 2020-2023  润新知