• day0420211230


    湖南

    day04数据库

    一.多表联查

    1.准备表和数据

    create table courses
    (
    cno varchar(5) not null,
    cname varchar(10) not null,
    tno varchar(3) not null,
    primary key (cno)
    );
    create table scores
    (
    sno varchar(3) not null,
    cno varchar(5) not null,
    degree numeric(10,1) not null,
    primary key (sno, cno)
    );
    
    create table students
    (
    sno varchar(3) not null,
    sname varchar(4) not null,
    ssex varchar(2) not null,
    sbirthday datetime,
    class varchar(5),
    primary key (sno)
    );
    
    create table teachers
    (
    tno varchar(3) not null,
    tname varchar(4),
    tsex varchar(2),
    tbirthday datetime,
    prof varchar(6),
    depart varchar(10),
    primary key (tno)
    );
    
    INSERT INTO STUDENTS (SNO,SNAME,SSEX,SBIRTHDAY,CLASS) VALUES (108 ,'曾华' ,'男' ,'1977-09-01',95033);
    INSERT INTO STUDENTS (SNO,SNAME,SSEX,SBIRTHDAY,CLASS) VALUES (105 ,'匡明' ,'男' ,'1975-10-02',95031);
    INSERT INTO STUDENTS (SNO,SNAME,SSEX,SBIRTHDAY,CLASS) VALUES (107 ,'王丽' ,'女' ,'1976-01-23',95033);
    INSERT INTO STUDENTS (SNO,SNAME,SSEX,SBIRTHDAY,CLASS) VALUES (101 ,'李军' ,'男' ,'1976-02-20',95033);
    INSERT INTO STUDENTS (SNO,SNAME,SSEX,SBIRTHDAY,CLASS) VALUES (109 ,'王芳' ,'女' ,'1975-02-10',95031);
    INSERT INTO STUDENTS (SNO,SNAME,SSEX,SBIRTHDAY,CLASS) VALUES (103 ,'陆君' ,'男' ,'1974-06-03',95031);
     
    INSERT INTO TEACHERS(TNO,TNAME,TSEX,TBIRTHDAY,PROF,DEPART) VALUES (804,'易天','男','1958-12-02','副教授','计算机系');
    INSERT INTO TEACHERS(TNO,TNAME,TSEX,TBIRTHDAY,PROF,DEPART) VALUES (856,'王旭','男','1969-03-12','讲师','电子工程系');
    INSERT INTO TEACHERS(TNO,TNAME,TSEX,TBIRTHDAY,PROF,DEPART) VALUES (825,'李萍','女','1972-05-05','助教','计算机系');
    INSERT INTO TEACHERS(TNO,TNAME,TSEX,TBIRTHDAY,PROF,DEPART) VALUES (831,'陈冰','女','1977-08-14','助教','电子工程系');
     
    INSERT INTO COURSES(CNO,CNAME,TNO)VALUES ('3-105' ,'计算机导论',825);
    INSERT INTO COURSES(CNO,CNAME,TNO)VALUES ('3-245' ,'操作系统' ,804);
    INSERT INTO COURSES(CNO,CNAME,TNO)VALUES ('6-166' ,'模拟电路' ,856);
    INSERT INTO COURSES(CNO,CNAME,TNO)VALUES ('6-106' ,'概率论' ,831);
    INSERT INTO COURSES(CNO,CNAME,TNO)VALUES ('9-888' ,'高等数学' ,831);
     
    INSERT INTO SCORES(SNO,CNO,DEGREE)VALUES (103,'3-245',86);
    INSERT INTO SCORES(SNO,CNO,DEGREE)VALUES (105,'3-245',75);
    INSERT INTO SCORES(SNO,CNO,DEGREE)VALUES (109,'3-245',68);
    INSERT INTO SCORES(SNO,CNO,DEGREE)VALUES (103,'3-105',92);
    INSERT INTO SCORES(SNO,CNO,DEGREE)VALUES (105,'3-105',88);
    INSERT INTO SCORES(SNO,CNO,DEGREE)VALUES (109,'3-105',76);
    INSERT INTO SCORES(SNO,CNO,DEGREE)VALUES (101,'3-105',64);
    INSERT INTO SCORES(SNO,CNO,DEGREE)VALUES (107,'3-105',91);
    INSERT INTO SCORES(SNO,CNO,DEGREE)VALUES (108,'3-105',78);
    INSERT INTO SCORES(SNO,CNO,DEGREE)VALUES (101,'6-166',85);
    INSERT INTO SCORES(SNO,CNO,DEGREE)VALUES (107,'6-106',79);
    INSERT INTO SCORES(SNO,CNO,DEGREE)VALUES (108,'6-166',81);
    

    二.笛卡尔积

    1.概述

    本质上就是把多张表,联合查询。要求,多张表用逗号隔开

    2.测试

    #多表联查:
    #1.笛卡尔积
    #练习1:查询部门表和员工表里的所有数据
    SELECT * FROM dept,emp
    #问题:产生了庞大的结果集,出现了重复的数据
    #练习2:查询部门表和员工表里的所有数据,添加过滤条件
    SELECT * FROM dept,emp
    WHERE dept.deptno=emp.deptno; #描述了两个表的关系
    #练习3:计算计算机导论课程所得的总分
          #聚合函数(表名.字段名)    表1,表2
    SELECT SUM(scores.degree) FROM courses,scores
    #描述了两个表的关系(表名.字段名)
    WHERE courses.cno=scores.cno
    AND courses.cname='计算机导论'#真正的业务条件
    #练习4:查询学员陆君的总得分 sno
    SELECT SUM(scores.degree) FROM scores,students
    WHERE scores.sno=students.sno#描述了两个表的关系(表名.字段名)
    AND students.sname='陆君'
    

    三.连接查询

    1.概述

    本质上就是把多张表,联合查询.要求,多张表用join连接

    2.测试

    #2.连接查询:join连接表,用on描述表关系
    #练习5:统计陈冰老师能讲的课程名称
    SELECT courses.cname FROM teachers JOIN courses
    ON teachers.tno=courses.tno#描述了两个表的关系
    WHERE teachers.tname='陈冰'#真正的业务条件
    #练习6:统计操作系统课程的总得分
    SELECT SUM(scores.degree) FROM courses JOIN scores
    ON courses.cno=scores.cno#描述了两个表的关系
    WHERE courses.cname='操作系统'#真正的业务条件
    #面试题:三种连接查询的区别?inner join/left join/right join
    #inner join内连接,取两个表的交集的数据
    #left join左外连接,取左表的所有和右表里满足条件的数据
    #right join右外连接,取右表的所有和左表里满足条件的数据
    
    #中午,自己测试三种区别???
    SELECT * FROM 
    dept INNER JOIN emp #内连接,取两张表的交集
    ON dept.deptno=emp.deptno
    SELECT * FROM 
    dept LEFT JOIN emp 
    #左连接,取左表的所有和右表满足条件的,不满足的填充null
    ON dept.deptno=emp.deptno
    SELECT * FROM 
    emp RIGHT JOIN dept
    #右连接,取右表的所有和左表满足条件的,不满足的填充null
    ON dept.deptno=emp.deptno
    

    四.子查询

    1.概述

    又叫嵌套查询,是指,把第一次的查询结果,作为第二次的查询条件,继续发起查询语句.

    2.测试

    #3.子查询
    #练习1:查询research部门的员工信息
    #第一次:查部门表,根据部门名称查部门编号
    SELECT deptno FROM dept WHERE dname='research'
    #第二次:查员工表,根据部门编号查询员工信息
    SELECT * FROM emp WHERE deptno=2
    #子查询:
    SELECT * FROM emp WHERE deptno=(
      SELECT deptno FROM dept WHERE dname='research'
    )
    #练习2:查询tony所在的部门名称
    #第1次:根据员工名字查部门编号
    SELECT deptno FROM emp WHERE ename='tony'
    #第2次:根据部门编号查部门名称
    SELECT dname FROM dept WHERE deptno=2
    #子查询:
    SELECT dname FROM dept WHERE deptno=(
     SELECT deptno FROM emp WHERE ename='tony'
    )
    #练习3:查询java开发部和research部门的员工姓名
    #第1次:根据部门名称查部门编号
    SELECT deptno FROM dept 
    WHERE dname='java开发部' OR dname='research'
    #第2次:根据编号查员工姓名
    SELECT ename FROM emp 
    #where deptno=1 or deptno=2
    WHERE deptno IN(1,2) #效果同上
    #子查询:第一次查到了多个结果,第二次查就要用in
    SELECT ename FROM emp WHERE deptno IN(
     SELECT deptno FROM dept 
      WHERE dname='java开发部' OR dname='research'
    )
    

    五.综合练习

    1.测试

    #综合练习:
    #练习1:查询可以讲高等数学的老师的名字
    #笛卡尔积
    SELECT tname FROM teachers,courses
    WHERE teachers.tno=courses.tno#描述两个表的关系
    AND courses.cname='高等数学'
    #连接查询
    SELECT tname FROM teachers a INNER JOIN courses b
    ON a.tno=b.tno#描述两个表的关系
    WHERE b.cname='高等数学'
    #子查询
    SELECT tname FROM teachers WHERE tno=(
     SELECT tno FROM courses WHERE cname='高等数学'
    )
    #练习2:查询学员曾华的总得分
    #笛卡尔积
    SELECT SUM(a.degree) FROM scores a,students b
    WHERE a.sno=b.sno  #描述两个表的关系
    AND  b.sname='曾华' #业务需求
    #连接查询
    SELECT SUM(a.degree) FROM scores a JOIN students b
    ON a.sno=b.sno  #描述两个表的关系
    WHERE  b.sname='曾华' #业务需求
    #子查询
    SELECT SUM(degree) FROM scores WHERE sno=(
     SELECT sno FROM students WHERE sname='曾华'
    )
    #查询高于平均工资的员工信息
    SELECT * FROM emp WHERE sal>(
     SELECT AVG(sal) FROM emp
    )
    

    六.扩展:索引

    1.概述

    用来提高数据库的查询效率
    分类:

    1. 单值索引:是指一个索引只包含着一个字段/列
    2. 复合索引:是指一个索引包含着多个字段/列
    3. 唯一索引:是一种特殊的单值索引,一个索引只包含着一个字段/列,这个字段的值要唯一

    2.测试

    #索引:提高查询效率,建议给经常用来查询的字段加索引
    #1.查看索引(主键自带索引)
    SHOW INDEX FROM students
    #2.创建单值索引
    #create index 索引名 on 表名(字段名)
    CREATE INDEX index1 ON students(sname)
    #3.使用索引(按照索引列去查)
    SELECT * FROM students WHERE sname='陆君'
    #4.查看SQL的执行性能/计划(只想关注你的SQL是否用到了索引)
    EXPLAIN #看执行结果里的key
    SELECT * FROM students WHERE sname='陆君'
    
    #5.创建唯一索引:找到合适的列,值要唯一
    #语法:create unique index 索引名 on 表名(字段名)
    #create unique index index2 on students(ssex)#不让加,ssex值大量重复
    CREATE UNIQUE INDEX index2 ON students(sno)
    SHOW INDEX FROM students#查看索引
    EXPLAIN SELECT * FROM students WHERE sno=101 #使用索引,索引失效!!
    #!!6.创建复合索引:一个索引包含着多个列
    CREATE INDEX index3 ON emp(ename,job,deptno)
    SHOW INDEX FROM emp#查看索引
    #使用索引,最左特性(查询条件里必须包含最左元素)
    EXPLAIN SELECT * FROM emp WHERE ename='jack'#复合索引生效
    EXPLAIN SELECT * FROM emp WHERE job='总监'#复合索引失效!
    EXPLAIN SELECT * FROM emp WHERE deptno=2#复合索引失效!
    EXPLAIN SELECT * FROM emp WHERE ename='jack' AND job='总监'#生效
    EXPLAIN SELECT * FROM emp WHERE job='总监' AND ename='jack'#生效
    EXPLAIN SELECT * FROM emp WHERE job='总监' OR ename='jack'#失效!
    #删除索引
    ALTER TABLE emp DROP INDEX index3
    

    3.总结

    1. 优点:
      大大提高了查询效率
      本质上数据库会为索引列的数据进行排序,快速查询
    2. 缺点
      本身索引是一个单独的表,也需要占空间的
      索引适合查询的业务,但是,也需要同步更新修改一些新的数据,需要一定的时间
    3. 原则:
      什么时候加索引?频繁的按照一个规则去查询的数据,就应该考虑添加索引
      给谁加索引?给那些经常作为查询条件的字段添加索引
      加啥索引?索引是有分类的,单值索引/唯一索引/复合索引,看情况选择不同的索引类型
      如何查看SQL的执行计划/性能?explain
  • 相关阅读:
    [读书笔记]SQLSERVER企业级平台管理实践读书笔记--从等待事件判断性能瓶颈
    Docker machine学习
    不同数据库连接字符串的网站
    Windows 可以操纵linux内文件,与本地一致的工具
    OpenSSH 安全漏洞(CVE-2021-28041)修复(升级OpenSSH至最新版本(8.6p1))
    PostgreSQL
    firewalld添加/删除服务service,端口port
    PostgreSQL 序列操作
    PostgreSQL/pgsql 为表添加列/ 判断列存不存在再添加列
    Windows10中Power Shell(x64)出现“无法加载 PSReadline 模块。控制台在未使用 PSReadline 的情况下运行。”的解决办法
  • 原文地址:https://www.cnblogs.com/elliottmoo/p/15748548.html
Copyright © 2020-2023  润新知