Ver código fonte

更新了数据库部分相关知识

jackfrued 6 anos atrás
pai
commit
66fb888d23

+ 132 - 151
Day36-40/code/SRS_create_and_init.sql

@@ -1,93 +1,74 @@
--- 关系型数据库可以保证数据的完整性
--- 实体完整性:每条记录都是独一无二的没有冗余 - 主键/唯一索引
--- 参照完整性(引用完整性):外键
--- 域完整性:数据类型、非空约束、默认值约束、检查约束
+-- 如果存在名为school的数据库就删除它
+drop database if exists school;
 
+-- 创建名为school的数据库并设置默认的字符集和排序方式
+create database school default charset utf8 collate utf8_bin;
 
--- 创建SRS数据库
-drop database if exists srs;
-create database srs default charset utf8 collate utf8_bin;
-
--- 切换到srs数据库
-use srs;
+-- 切换到school数据库上下文环境
+use school;
 
 -- 创建学院表
 create table tb_college
 (
-collid int not null auto_increment comment '学院编号',
-collname varchar(50) not null comment '学院名称',
-collmaster varchar(20) not null comment '院长姓名',
-collweb varchar(511) default '' comment '学院网站',
+collid int not null auto_increment comment '编号',
+collname varchar(50) not null comment '名称',
+collmaster varchar(20) not null comment '院长',
+collweb varchar(511) default '' comment '网站',
 primary key (collid)
 );
 
--- 添加唯一约束
-alter table tb_college add constraint uni_college_collname unique (collname);
-
 -- 创建学生表
 create table tb_student
 (
 stuid int not null comment '学号',
-sname varchar(20) not null comment '学生姓名',
-gender bit default 1 comment '性别',
-birth date not null comment '出生日期',
-addr varchar(255) default '' comment '籍贯',
-collid int not null comment '所属学院编号',
-primary key (stuid)
+stuname varchar(20) not null comment '姓名',
+stusex bit default 1 comment '性别',
+stubirth date not null comment '出生日期',
+stuaddr varchar(255) default '' comment '籍贯',
+collid int not null comment '所属学院',
+primary key (stuid),
+foreign key (collid) references tb_college (collid)
 );
 
--- 检查约束(MySQL不支持它)
-alter table tb_student add constraint ck_student_birth 
-check (birth between '1990-1-1' and '1999-12-31');
-
--- 添加外键约束
-alter table tb_student add constraint fk_student_collid foreign key (collid) references tb_college (collid);
+-- alter table tb_student add constraint fk_student_collid foreign key (collid) references tb_college (collid);
 
 -- 创建教师表
 create table tb_teacher
 (
-teaid int not null comment '教师工号',
-tname varchar(20) not null comment '教师姓名',
-title varchar(10) default '' comment '职称',
-collid int not null comment '所属学院编号'
+teaid int not null comment '工号',
+teaname varchar(20) not null comment '姓名',
+teatitle varchar(10) default '助教' comment '职称',
+collid int not null comment '所属学院',
+primary key (teaid),
+foreign key (collid) references tb_college (collid)
 );
 
--- 添加主键约束
-alter table tb_teacher add constraint pk_teacher primary key (teaid);
-
--- 添加外键约束
-alter table tb_teacher add constraint fk_teacher_collid foreign key (collid) references tb_college (collid);
-
 -- 创建课程表
 create table tb_course
 (
-couid int not null comment '课程编号',
-cname varchar(50) not null comment '课程名称',
-credit tinyint not null comment '学分',
-teaid int not null comment '教师工号',
-primary key (couid)
+couid int not null comment '编号',
+couname varchar(50) not null comment '名称',
+coucredit int not null comment '学分',
+teaid int not null comment '授课老师',
+primary key (couid),
+foreign key (teaid) references tb_teacher (teaid)
 );
 
--- 添加外键约束
-alter table tb_course add constraint fk_course_tid foreign key (teaid) references tb_teacher (teaid);
-
--- 创建学生选课表
+-- 创建选课记录表
 create table tb_score
 (
-scid int not null auto_increment comment '选课编号',
-sid int not null comment '学号',
-cid int not null comment '课程编号',
-seldate date comment '选课时间日期',
-mark decimal(4,1) comment '考试成绩',
-primary key (scid)
+scid int auto_increment comment '选课记录编号',
+stuid int not null comment '选课学生',
+couid int not null comment '所选课程',
+scdate datetime comment '选课时间日期',
+scmark decimal(4,1) comment '考试成绩',
+primary key (scid),
+foreign key (stuid) references tb_student (stuid),
+foreign key (couid) references tb_course (couid)
 );
 
--- 添加外键约束
-alter table tb_score add constraint fk_score_sid foreign key (sid) references tb_student (stuid);
-alter table tb_score add constraint fk_score_cid foreign key (cid) references tb_course (couid);
--- 添加唯一约束
-alter table tb_score add constraint uni_score_sid_cid unique (sid, cid);
-
+-- 添加唯一性约束(一个学生选某个课程只能选一次)
+alter table tb_score add constraint uni_score_stuid_couid unique (stuid, couid);
 
 -- 插入学院数据
 insert into tb_college (collname, collmaster, collweb) values 
@@ -96,7 +77,7 @@ insert into tb_college (collname, collmaster, collweb) values
 ('经济管理学院', '风清扬', 'http://www.foo.com');
 
 -- 插入学生数据
-insert into tb_student (stuid, sname, gender, birth, addr, collid) values
+insert into tb_student (stuid, stuname, stusex, stubirth, stuaddr, collid) values
 (1001, '杨逍', 1, '1990-3-4', '四川成都', 1),
 (1002, '任我行', 1, '1992-2-2', '湖南长沙', 1),
 (1033, '王语嫣', 0, '1989-12-3', '四川成都', 1),
@@ -109,7 +90,7 @@ insert into tb_student (stuid, sname, gender, birth, addr, collid) values
 (3923, '杨不悔', 0, '1985-4-17', '四川成都', 3);
 
 -- 插入老师数据
-insert into tb_teacher (teaid, tname, title, collid) values 
+insert into tb_teacher (teaid, teaname, teatitle, collid) values 
 (1122, '张三丰', '教授', 1),
 (1133, '宋远桥', '副教授', 1),
 (1144, '杨逍', '副教授', 1),
@@ -117,7 +98,7 @@ insert into tb_teacher (teaid, tname, title, collid) values
 (3366, '韦一笑', '讲师', 3);
 
 -- 插入课程数据
-insert into tb_course (couid, cname, credit, teaid) values 
+insert into tb_course (couid, couname, coucredit, teaid) values 
 (1111, 'Python程序设计', 3, 1122),
 (2222, 'Web前端开发', 2, 1122),
 (3333, '操作系统', 4, 1122),
@@ -129,7 +110,7 @@ insert into tb_course (couid, cname, credit, teaid) values
 (9999, '审计学', 3, 3366);
 
 -- 插入选课数据
-insert into tb_score (sid, cid, seldate, mark) values 
+insert into tb_score (stuid, couid, scdate, scmark) values 
 (1001, 1111, '2017-09-01', 95),
 (1001, 2222, '2017-09-01', 87.5),
 (1001, 3333, '2017-09-01', 100),
@@ -151,111 +132,111 @@ insert into tb_score (sid, cid, seldate, mark) values
 
 -- 查询所有学生信息
 select * from tb_student;
+
 -- 查询所有课程名称及学分(投影和别名)
-select cname as 课程名称, credit as 学分 from tb_course;
+select couname, coucredit from tb_course;
+select couname as 课程名称, coucredit as 学分 from tb_course;
+
+select stuname as 姓名, case stusex when 1 then '男' else '女' end as 性别 from tb_student;
+select stuname as 姓名, if(stusex, '男', '女') as 性别 from tb_student;
+
 -- 查询所有女学生的姓名和出生日期(筛选)
-select sname as 姓名, birth as 出生日期 from tb_student where gender=0;
+select stuname, stubirth from tb_student where stusex=0;
+
 -- 查询所有80后学生的姓名、性别和出生日期(筛选)
-select sname, gender, birth from tb_student where birth between '1980-1-1' and '1989-12-31';
--- 查询姓”杨“的学生姓名和性别(模糊)
-select sname, gender from tb_student where sname like '杨%';
--- 查询姓”杨“名字两个字的学生姓名和性别(模糊)
-select sname, gender from tb_student where sname like '杨_';
--- 查询姓”杨“名字三个字的学生姓名和性别(模糊)
-select sname, gender from tb_student where sname like '杨__';
--- 查询名字中有”不“字或“嫣”字的学生的姓名(模糊)
-select sname from tb_student where sname like '%不%' or sname like '%嫣%';
+select stuname, stusex, stubirth from tb_student where stubirth>='1980-1-1' and stubirth<='1989-12-31';
+select stuname, stusex, stubirth from tb_student where stubirth between '1980-1-1' and '1989-12-31';
+
+-- 查询姓"杨"的学生姓名和性别(模糊)
+select stuname, stusex from tb_student where stuname like '杨%';
+
+-- 查询姓"杨"名字两个字的学生姓名和性别(模糊)
+select stuname, stusex from tb_student where stuname like '杨_';
+
+-- 查询姓"杨"名字三个字的学生姓名和性别(模糊)
+select stuname, stusex from tb_student where stuname like '杨__';
+
+-- 查询名字中有"不"字或"嫣"字的学生的姓名(模糊)
+select stuname, stusex from tb_student where stuname like '%不%' or stuname like '%嫣%';
+
 -- 查询没有录入家庭住址的学生姓名(空值)
-select sname from tb_student where addr is null or addr='';
+select stuname from tb_student where stuaddr is null;
+
 -- 查询录入了家庭住址的学生姓名(空值)
-select sname from tb_student where addr is not null and addr<>'';
+select stuname from tb_student where stuaddr is not null;
+
 -- 查询学生选课的所有日期(去重)
-select distinct seldate from tb_score;
+select distinct scdate from tb_score;
+
 -- 查询学生的家庭住址(去重)
-select distinct addr from tb_student where addr is not null and addr<>'';
+select distinct stuaddr from tb_student where stuaddr is not null;
+
 -- 查询男学生的姓名和生日按年龄从大到小排列(排序)
-select sname, birth from tb_student where gender=1 order by birth asc;
--- max() / min() / sum() / avg() / count()
+-- asc - ascending - 升序(从小到大)
+-- desc - descending - 降序(从大到小)
+select stuname as 姓名, year(now())-year(stubirth) as 年龄 from tb_student where stusex=1 order by 年龄 desc;
+
+-- 聚合函数:max / min / count / sum / avg
 -- 查询年龄最大的学生的出生日期(聚合函数)
-select min(birth) from tb_student;
+select min(stubirth) from tb_student;
+
 -- 查询年龄最小的学生的出生日期(聚合函数)
-select max(birth) from tb_student;
+select max(stubirth) from tb_student;
+
 -- 查询男女学生的人数(分组和聚合函数)
-select if(gender, '男', '女') as 性别, count(gender) as 人数 
-from tb_student group by gender;
+select count(stuid) from tb_student;
+select stusex, count(*) from tb_student group by stusex;
+select stusex, min(stubirth) from tb_student group by stusex;
+
 -- 查询课程编号为1111的课程的平均成绩(筛选和聚合函数)
-select avg(mark) as 平均分 from tb_score where cid=1111;
+select avg(scmark) from tb_score where couid=1111;
+select min(scmark) from tb_score where couid=1111;
+select count(scid) from tb_score where couid=1111;
+select count(scmark) from tb_score where couid=1111;
+
 -- 查询学号为1001的学生所有课程的平均分(筛选和聚合函数)
-select avg(mark) as 平均分 from tb_score where sid=1001;
+select avg(scmark) from tb_score where stuid=1001;
+
 -- 查询每个学生的学号和平均成绩(分组和聚合函数)
-select sid, avg(mark) from tb_score where mark is not null group by sid;
+select stuid as 学号, avg(scmark) as 平均分 from tb_score group by stuid;
+
 -- 查询平均成绩大于等于90分的学生的学号和平均成绩
-select sid, avg(mark) from tb_score group by sid having avg(mark)>=90;
--- 子查询 - 在一个查询中又使用到了另外一个查询的结果
--- 查询年龄最大的学生的姓名(子查询)
-select sname from tb_student where birth=(select min(birth) from tb_student);
+-- 分组以前的筛选使用where子句
+-- 分组以后的筛选使用having子句
+select stuid as 学号, avg(scmark) as 平均分 from tb_score group by stuid having 平均分>=90;
+
+-- 查询年龄最大的学生的姓名(子查询/嵌套的查询)
+select stuname from tb_student where stubirth=(
+	select min(stubirth) from tb_student
+);
+
 -- 查询年龄最大的学生姓名和年龄(子查询+运算)
-select sname as 姓名, year(now()) - year(birth) as 年龄 
-from tb_student where birth=(select min(birth) from tb_student);
+select stuname as 姓名, year(now())-year(stubirth) as 年龄 from tb_student where stubirth=(
+	select min(stubirth) from tb_student
+);
+
 -- 查询选了两门以上的课程的学生姓名(子查询/分组条件/集合运算)
-select sname from tb_student where stuid in ( 
-select sid from tb_score group by sid having count(sid)>2);
--- 连接查询(联结查询/联接查询)
--- 查询学生姓名、课程名称以及成绩
-select sname, cname, mark 
-from tb_score t1, tb_student t2, tb_course t3 
-where t2.stuid=t1.sid and t3.couid=t1.cid and mark is not null;
-
-select sname, cname, mark from tb_student t1 
-inner join tb_score t2 on t1.stuid=t2.sid 
-inner join tb_course t3 on t3.couid=t2.cid 
-where mark is not null;
+select stuname from tb_student where stuid=(
+	select stuid from tb_score group by stuid having count(stuid)>2
+)
+
+-- 查询学生姓名、课程名称以及成绩(连接查询)
+select stuname, couname, scmark from tb_student t1, tb_course t2, tb_score t3 where t1.stuid=t3.stuid and t2.couid=t3.couid and scmark is not null;
+
+select stuname, couname, scmark from tb_student t1 inner join tb_score t3 on t1.stuid=t3.stuid inner join tb_course t2 on t2.couid=t3.couid where scmark is not null order by scmark desc limit 5 offset 10;
+
+select stuname, couname, scmark from tb_student t1 inner join tb_score t3 on t1.stuid=t3.stuid inner join tb_course t2 on t2.couid=t3.couid where scmark is not null order by scmark desc limit 10, 5;
+
+-- 单表:65535TB
+-- 单列:4G - LONGBLOB (Binary Large OBject) / LONGTEXT
 -- 查询选课学生的姓名和平均成绩(子查询和连接查询)
-select sname, avgmark from tb_student t1, 
-(select sid, avg(mark) as avgmark from tb_score group by sid) t2 
-where stuid=sid;
+select stuname, avgmark from tb_student t1, (select stuid, avg(scmark) as avgmark from tb_score group by stuid) t2 where t1.stuid=t2.stuid;
 
-select sname, avgmark from tb_student inner join 
-(select sid, avg(mark) as avgmark from tb_score group by sid) t2 
-on stuid=sid;
--- 注意:在连接查询时如果没有给出连接条件就会形成笛卡尔积
+select stuname, avgmark from tb_student t1 inner join 
+(select stuid, avg(scmark) as avgmark from tb_score group by stuid) t2 on t1.stuid=t2.stuid;
 
+-- 内连接(inner join):只有满足连接条件的记录才会被查出来
+-- 外连接(outer join):左外连接 / 右外连接 / 全外连接
+-- left outer join / right outer join / full outer join
 -- 查询每个学生的姓名和选课数量(左外连接和子查询)
--- 左外连接 - 把左表(写在前面的表)不满足连接条件的记录也查出来对应记录补null值
--- 右外连接 - 把右表(写在后面的表)不满足连接条件的记录也查出来对应记录补null值
-select sname, total from tb_student left join 
-(select sid, count(sid) as total from tb_score group by sid) tb_temp 
-on stuid=sid;
-
--- DDL (Data Definition Language)
--- DML (Data Manipulation Language)
--- DCL (Data Control Language)
-
--- 创建名为hellokitty的用户并设置口令
-create user 'hellokitty'@'%' identified by '123123';
-
--- 授权
-grant select on srs.* to 'hellokitty'@'%';
-grant insert, delete, update on srs.* to 'hellokitty'@'%';
-grant create, drop, alter on srs.* to 'hellokitty'@'%';
-
-grant all privileges on srs.* to 'hellokitty'@'%';
-grant all privileges on srs.* to 'hellokitty'@'%' with grant option;
-
--- 召回
-revoke all privileges on srs.* from 'hellokitty'@'%';
-
--- 事务控制
--- 开启事务环境
-begin;
--- start transaction;
-update tb_score set mark=mark-2 where sid=1001 and mark is not null;
-update tb_score set mark=mark+2 where sid=1002 and mark is not null;
--- 事务提交
-commit;
- -- 事务回滚
-rollback;
-
-begin;
-delete from tb_score;
-rollback;
+select stuname, ifnull(total, 0) from tb_student t1 left outer join (select stuid, count(stuid) as total from tb_score group by stuid) t2 on t1.stuid=t2.stuid;

+ 19 - 2
Day36-40/code/contact/main.py

@@ -1,3 +1,20 @@
+"""
+-- 创建名为address的数据库
+create database address default charset utf8;
+
+-- 切换到address数据库
+use address;
+
+-- 创建联系人表tb_contacter
+create table tb_contacter
+(
+conid int auto_increment comment '编号',
+conname varchar(31) not null comment '姓名',
+contel varchar(15) default '' comment '电话',
+conemail varchar(255) default'' comment '邮箱',
+primary key (conid)
+);
+"""
 import pymysql
 
 INSERT_CONTACTER = """
@@ -154,9 +171,9 @@ def find_contacters(con):
 
 
 def main():
-    con = pymysql.connect(host='localhost', port=3306,
+    con = pymysql.connect(host='120.77.222.217', port=3306,
                           user='root', passwd='123456',
-                          db='contact', charset='utf8',
+                          db='address', charset='utf8',
                           autocommit=True,
                           cursorclass=pymysql.cursors.DictCursor)
     while True:

+ 0 - 8
Day36-40/code/contact/test01.py

@@ -1,8 +0,0 @@
-def main():
-    list1 = ['orange', 'grape', 'banana', 'waxberry', 'pitaya']
-    for index, val in enumerate(list1):
-        print('%d: %s' % (index, val))
-
-
-if __name__ == '__main__':
-    main()

+ 0 - 32
Day36-40/code/contact/test02.py

@@ -1,32 +0,0 @@
-class Student(object):
-
-    def __init__(self, id, name, age, sex):
-        self.id = id
-        self.name = name
-        self.age = age
-        self.sex = sex
-
-    def study(self, course_name):
-        print(f'{self.name}正在学习{course_name}.')
-
-    def watch_av(self):
-        if self.age >= 18:
-            print(f'{self.name}正在观看岛国片.')
-        else:
-            print(f'{self.name}只能看《熊出没》.')
-
-
-def main():
-    dict1 = {
-        'id': 1001,
-        'name': '王大锤',
-        'age': 15,
-        'sex': True
-    }
-    stu = Student(**dict1)
-    stu.study('Python程序设计')
-    stu.watch_av()
-
-
-if __name__ == '__main__':
-    main()

+ 16 - 16
Day36-40/code/library_create_and_init.sql

@@ -1,10 +1,10 @@
-drop database if exists Library;
+drop database if exists library;
 
-create database Library default charset utf8;
+create database library default charset utf8;
 
-use Library;
+use library;
 
-create table TbBook
+create table tb_book
 (
 bookid integer primary key auto_increment,
 title varchar(100) not null,
@@ -16,16 +16,16 @@ lenddate datetime,
 lendcount integer default 0
 );
 
-insert into TbBook (title, author, publisher, price, lendcount) values ('Java核心技术(卷1)', '凯 S.霍斯特曼', '机械工业出版社', 98.2, 102);
-insert into TbBook (title, author, publisher, price, lendcount) values ('Java编程思想', '埃史尔', '机械工业出版社', 86.4, 87);
-insert into TbBook (title, author, publisher, price, lendcount) values ('深入理解Java虚拟机', '周志明', '机械工业出版社', 64.4, 32);
-insert into TbBook (title, author, publisher, price, lendcount) values ('Effective Java中文版(第2版) ', '埃史尔', '机械工业出版社', 36.8, 200);
-insert into TbBook (title, author, publisher, price, lendcount) values ('数据结构与算法分析:Java语言描述(原书第3版)', '马克·艾伦·维斯', '机械工业出版社', 51.0, 15);
-insert into TbBook (title, author, publisher, price, lendcount) values ('Java 8实战', '厄马', '人民邮电出版社', 56.8, 25);
-insert into TbBook (title, author, publisher, price, lendcount) values ('重构:改善既有代码的设计', '马丁·福勒', '人民邮电出版社', 53.1, 99);
-insert into TbBook (title, author, publisher, price, lendcount) values ('代码大全(第2版)', '史蒂夫•迈克康奈尔', '电子工业出版社', 53.1, 99);
-insert into TbBook (title, author, publisher, price, lendcount) values ('程序员修炼之道:从小工到专家', '亨特, 托马斯', '电子工业出版社', 45.4, 50);
-insert into TbBook (title, author, publisher, price, lendcount) values ('代码整洁之道', '马丁', '人民邮电出版社', 45.4, 30);
-insert into TbBook (title, author, publisher, price, lendcount) values ('设计模式 可复用面向对象软件的基础', 'Erich Gamma, Richard Helm', '机械工业出版社', 30.2, 77);
-insert into TbBook (title, author, publisher, price, lendcount) values ('设计模式之禅(第2版)', '秦小波', '机械工业出版社', 70.4, 100);
+insert into tb_book (title, author, publisher, price, lendcount) values ('Java核心技术(卷1)', '凯 S.霍斯特曼', '机械工业出版社', 98.2, 102);
+insert into tb_book (title, author, publisher, price, lendcount) values ('Java编程思想', '埃史尔', '机械工业出版社', 86.4, 87);
+insert into tb_book (title, author, publisher, price, lendcount) values ('深入理解Java虚拟机', '周志明', '机械工业出版社', 64.4, 32);
+insert into tb_book (title, author, publisher, price, lendcount) values ('Effective Java中文版(第2版) ', '埃史尔', '机械工业出版社', 36.8, 200);
+insert into tb_book (title, author, publisher, price, lendcount) values ('数据结构与算法分析:Java语言描述(原书第3版)', '马克·艾伦·维斯', '机械工业出版社', 51.0, 15);
+insert into tb_book (title, author, publisher, price, lendcount) values ('Java 8实战', '厄马', '人民邮电出版社', 56.8, 25);
+insert into tb_book (title, author, publisher, price, lendcount) values ('重构:改善既有代码的设计', '马丁·福勒', '人民邮电出版社', 53.1, 99);
+insert into tb_book (title, author, publisher, price, lendcount) values ('代码大全(第2版)', '史蒂夫•迈克康奈尔', '电子工业出版社', 53.1, 99);
+insert into tb_book (title, author, publisher, price, lendcount) values ('程序员修炼之道:从小工到专家', '亨特, 托马斯', '电子工业出版社', 45.4, 50);
+insert into tb_book (title, author, publisher, price, lendcount) values ('代码整洁之道', '马丁', '人民邮电出版社', 45.4, 30);
+insert into tb_book (title, author, publisher, price, lendcount) values ('设计模式 可复用面向对象软件的基础', 'Erich Gamma, Richard Helm', '机械工业出版社', 30.2, 77);
+insert into tb_book (title, author, publisher, price, lendcount) values ('设计模式之禅(第2版)', '秦小波', '机械工业出版社', 70.4, 100);
 

+ 6 - 3
Day36-40/code/shop_create_sql.sql

@@ -1,6 +1,8 @@
-drop database if exists Shop;
-create database Shop default charset utf8;
-use Shop;
+drop database if exists shop;
+create database shop default charset utf8;
+	
+use shop;
+
 drop table if exists tb_goods;
 create table tb_goods
 (
@@ -10,6 +12,7 @@ gprice decimal(10,2) not null,
 gimage varchar(255),
 primary key (gid)
 );
+
 insert into tb_goods values 
 (default, '乐事(Lay’s)无限薯片', 8.2, 'images/lay.jpg'),
 (default, '旺旺 仙贝 加量装 540g', 18.5, 'images/wang.jpg'),

+ 0 - 2
Day36-40/code/srs_exercise_origin.sql

@@ -1,5 +1,3 @@
-use SRS;
-
 -- 查询所有学生信息
 
 -- 查询所有课程名称及学分(投影和别名)

+ 877 - 0
Day36-40/code/人力资源管理.spf

@@ -0,0 +1,877 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+	<key>ContentFilters</key>
+	<dict/>
+	<key>auto_connect</key>
+	<true/>
+	<key>data</key>
+	<dict>
+		<key>connection</key>
+		<dict>
+			<key>database</key>
+			<string>hrs</string>
+			<key>host</key>
+			<string>120.77.222.217</string>
+			<key>kcid</key>
+			<string>6157604644212181126</string>
+			<key>name</key>
+			<string>MySQL@Aliyun</string>
+			<key>rdbms_type</key>
+			<string>mysql</string>
+			<key>sslCACertFileLocation</key>
+			<string></string>
+			<key>sslCACertFileLocationEnabled</key>
+			<integer>0</integer>
+			<key>sslCertificateFileLocation</key>
+			<string></string>
+			<key>sslCertificateFileLocationEnabled</key>
+			<integer>0</integer>
+			<key>sslKeyFileLocation</key>
+			<string></string>
+			<key>sslKeyFileLocationEnabled</key>
+			<integer>0</integer>
+			<key>type</key>
+			<string>SPTCPIPConnection</string>
+			<key>useSSL</key>
+			<integer>0</integer>
+			<key>user</key>
+			<string>root</string>
+		</dict>
+		<key>session</key>
+		<dict>
+			<key>connectionEncoding</key>
+			<string>utf8</string>
+			<key>contentPageNumber</key>
+			<integer>1</integer>
+			<key>contentSelection</key>
+			<data>
+			YnBsaXN0MDDUAQIDBAUGOTpYJHZlcnNpb25YJG9iamVjdHNZJGFy
+			Y2hpdmVyVCR0b3ASAAGGoK0HCBUWFxgZHSQoLDE2VSRudWxs0wkK
+			CwwQFFdOUy5rZXlzWk5TLm9iamVjdHNWJGNsYXNzow0OD4ACgAOA
+			BKMREhOABYAGgAiADFR0eXBlVHJvd3NUa2V5c18QJlNlbGVjdGlv
+			bkRldGFpbFR5cGVQcmltYXJ5S2V5ZWREZXRhaWxz0wkKCxobHKCg
+			gAfSHh8gIVokY2xhc3NuYW1lWCRjbGFzc2VzXxATTlNNdXRhYmxl
+			RGljdGlvbmFyeaMgIiNcTlNEaWN0aW9uYXJ5WE5TT2JqZWN00goL
+			JSehJoAJgAvSCykqK1lOUy5zdHJpbmeAClNlbm/SHh8tLl8QD05T
+			TXV0YWJsZVN0cmluZ6MtLzBYTlNTdHJpbmdYTlNPYmplY3TSHh8y
+			M15OU011dGFibGVBcnJheaMyNDVXTlNBcnJheVhOU09iamVjdNIe
+			HyI3oiI4WE5TT2JqZWN0XxAPTlNLZXllZEFyY2hpdmVy0Ts8VGRh
+			dGGAAQAIABEAGgAjAC0AMgA3AEUASwBSAFoAZQBsAHAAcgB0AHYA
+			egB8AH4AgACCAIcAjACRALoAwQDCAMMAxQDKANUA3gD0APgBBQEO
+			ARMBFQEXARkBHgEoASoBLgEzAUUBSQFSAVsBYAFvAXMBewGEAYkB
+			jAGVAacBqgGvAAAAAAAAAgEAAAAAAAAAPQAAAAAAAAAAAAAAAAAA
+			AbE=
+			</data>
+			<key>contentSortColIsAsc</key>
+			<true/>
+			<key>contentViewport</key>
+			<string>{{0, 0}, {694, 448}}</string>
+			<key>isToolbarVisible</key>
+			<true/>
+			<key>queries</key>
+			<string>-- 注意事项:
+-- 1. 给数据库和表命名的时候尽量使用全小写
+-- 2. 作为筛选条件的字符串是否区分大小看设置的校对规则
+drop database if exists hrs;
+create database hrs default charset utf8 collate utf8_general_ci;
+
+use hrs;
+
+drop table if exists tb_emp;
+drop table if exists tb_dept;
+
+-- 3. 数据库中的对象通常会用前缀加以区分
+-- table / view / index / function / procedure / trigger
+create table tb_dept
+(
+dno int not null comment '编号',
+dname varchar(10) not null comment '名称',
+dloc varchar(20) not null comment '所在地',
+primary key (dno)
+);
+
+-- 批量插入操作
+insert into tb_dept values 
+	(10, '会计部', '北京'),
+	(20, '研发部', '成都'),
+	(30, '销售部', '重庆'),
+	(40, '运维部', '深圳');
+
+create table tb_emp
+(
+eno int not null comment '员工编号',
+ename varchar(20) not null comment '员工姓名',
+job varchar(20) not null comment '员工职位',
+mgr int comment '主管编号',
+sal int not null comment '员工月薪',
+comm int comment '每月补贴',
+dno int comment '所在部门编号',
+primary key (eno)
+);
+
+-- 修改表添加一个列到mgr列的后面
+-- alter table tb_emp add column hiredate date after mgr;
+
+-- 修改表添加一个自参照的外键约束
+-- alter table tb_emp add constraint fk_emp_mgr foreign key (mgr) references tb_emp (eno);
+
+-- alter table tb_emp drop foreign key fk_emp_mgr;
+
+-- alter table tb_emp drop foreign key fk_emp_dno;
+
+-- restrict - 不允许操作
+-- cascade - 级联操作
+-- set null - 设置为null
+alter table tb_emp add constraint fk_emp_dno foreign key (dno) references tb_dept (dno); 
+-- on delete restrict on update cascade;
+
+insert into tb_emp values 
+	(7800, '张三丰', '总裁', null, 9000, 1200, 20),
+	(2056, '乔峰', '分析师', 7800, 5000, 1500, 20),
+	(3088, '李莫愁', '设计师', 2056, 3500, 800, 20),
+	(3211, '张无忌', '程序员', 2056, 3200, null, 20),
+	(3233, '丘处机', '程序员', 2056, 3400, null, 20),
+	(3251, '张翠山', '程序员', 2056, 4000, null, 20),
+	(5566, '宋远桥', '会计师', 7800, 4000, 1000, 10),
+	(5234, '郭靖', '出纳', 5566, 2000, null, 10),
+	(3344, '黄蓉', '销售主管', 7800, 3000, 800, 30),
+	(1359, '胡一刀', '销售员', 3344, 1800, 200, 30),
+	(4466, '苗人凤', '销售员', 3344, 2500, null, 30),
+	(3244, '欧阳锋', '程序员', 3088, 3200, null, 20),
+	(3577, '杨过', '会计', 5566, 2200, null, 10),
+	(3588, '朱九真', '会计', 5566, 2500, null, 10);
+
+-- 查询月薪最高的员工姓名和工资 - 子查询/嵌套查询+聚合函数
+-- select ename, sal from tb_emp order by sal desc limit 1;
+select ename, sal from tb_emp where sal=(
+	select max(sal) from tb_emp
+);
+
+-- 查询员工的姓名和年薪((月薪+补贴)*12)
+select ename, (sal+ifnull(comm, 0))*12 as 年薪 from tb_emp order by 年薪 desc;
+
+-- 查询有员工的部门的编号和人数 - 分组查询+聚合函数
+select dno, count(dno) from tb_emp group by dno with rollup;
+
+-- 查询所有部门的名称和人数 - 子查询+连接查询(左外)
+select dname as 部门名称, ifnull(total, 0) as 人数 from tb_dept t1 left join (select dno, count(dno) as total from tb_emp group by dno) t2 on t1.dno=t2.dno;
+
+-- 查询月薪最高的员工(Boss除外)的姓名和工资 - 空值判断
+select ename, sal from tb_emp where sal=(select max(sal) from tb_emp where mgr is not null);
+
+-- 查询月薪超过平均薪水的员工的姓名和工资
+select ename, sal from tb_emp where sal&gt;(select avg(sal) as avgsal from tb_emp);
+
+-- 查询月薪超过其所在部门平均薪水的员工的姓名、部门编号和工资
+select ename, t1.dno, sal, round(avgsal, 2) from tb_emp t1 inner join (select dno, avg(sal) as avgsal from tb_emp group by dno) t2 on t1.dno=t2.dno where sal&gt;avgsal;
+
+-- 查询部门中薪水最高的人姓名、工资和所在部门名称
+select ename, sal, dname from (select ename, sal, t1.dno from tb_emp t1 inner join (select dno, max(sal) as maxsal from tb_emp group by dno) t2 on t1.dno=t2.dno where sal=maxsal) t3 inner join tb_dept t4 on t3.dno=t4.dno;
+
+-- 查询主管的姓名和职位
+select ename, job from tb_emp where eno in (select distinct mgr from tb_emp where mgr is not null);
+
+-- 通常不推荐使用in或者not in集合运算和distinct去重操作
+-- 可以考虑用exists或not exists替代掉集合运算和去重操作
+select ename, job from tb_emp t1 where exists (select 'x' from tb_emp t2 where t1.eno=t2.mgr);
+
+-- 查询月薪排名4~6名的员工姓名和工资
+select ename, sal from tb_emp order by sal desc limit 3, 3;
+select ename, sal from tb_emp order by sal desc limit 3 offset 3;
+
+-- explain生成执行计划
+explain select eno, ename from tb_emp where eno=7800;
+explain select eno, ename from tb_emp where eno&lt;&gt;7900;
+explain select eno, ename from tb_emp where ename='张三丰';
+explain select eno, ename from tb_emp where ename like '张%';
+explain select eno, ename from tb_emp where ename like '%张';
+explain select eno, ename from tb_emp where ename&lt;&gt;'张三丰';
+
+-- 视图:查询的快照(简化查询操作)
+-- 通过视图可以将用户的访问权限限制到某些指定的列上
+create view vw_emp_dept as 
+select eno, ename, dname from tb_emp t1 inner join tb_dept t2 on t1.dno=t2.dno;
+
+select ename, dname from vw_emp_dept;
+
+drop view vw_emp_dept;
+
+-- 索引(index)
+-- 索引可以加速查询所以应该在经常用于查询筛选条件的列上建立索引
+-- 索引会使用额外的存储空间而且会让增删改变得更慢(因为要更新索引)
+-- 所以不能够滥用索引
+create index idx_emp_ename on tb_emp (ename);
+drop index idx_emp_ename on tb_emp;
+
+-- (存储)过程/函数:把一系列的SQL可以封装到一个过程中,而且可以加上分支和循环,将来通过过程的名字直接调用过程即可,因为创建过程时已经提前编译了SQL语句,所以比直接执行SQL语句性能更好
+
+-- 重新定义定界符为$$
+delimiter $$
+
+-- 创建存储过程
+create procedure sp_dept_avg_sal(deptno int, out avgsal float)
+begin
+	select avg(sal) into avgsal from tb_emp where dno=deptno;
+end$$
+
+-- 将定界符还原回;
+delimiter ;
+
+-- 调用存储过程
+call sp_dept_avg_sal(20, @a);
+
+-- 通过输出参数取出部门平均工资
+select @a;
+
+-- 删除存储过程
+drop procedure sp_dept_avg_sal;
+
+-- 触发器:在执行增删改操作时可以触发其他的级联操作,但是有可能导致“锁表”现象,实际开发中应该尽量避免使用触发器
+-- update tb_dept set dno=11 where dno=10;
+-- delete from tb_dept where dno=11;
+
+delimiter $$
+
+create trigger tr_dept_update 
+after update on tb_dept for each row
+begin
+	update tb_emp set dno=new.dno where dno=old.dno;
+end$$
+
+delimiter ;
+
+drop trigger tr_dept_update;
+
+-- DCL:授予权限(grant to)和召回权限(revoke from)
+create user 'hellokitty'@'%' identified by '123123';
+
+grant all privileges on hrs.* to 'hellokitty'@'%';
+
+revoke insert, delete, update on hrs.* from 'hellokitty'@'%';
+
+drop user 'hellokitty'@'%';
+
+-- 事务(transaction)- 把多个增删改的操作做成不可分割的原子性操作
+-- 要么全部都做,要么全都不做
+
+-- start transaction;
+begin;
+
+delete from tb_emp;
+
+
+</string>
+			<key>table</key>
+			<string>tb_emp</string>
+			<key>view</key>
+			<string>SP_VIEW_CUSTOMQUERY</string>
+			<key>windowVerticalDividerPosition</key>
+			<real>163</real>
+		</dict>
+	</dict>
+	<key>encrypted</key>
+	<false/>
+	<key>format</key>
+	<string>connection</string>
+	<key>queryFavorites</key>
+	<array/>
+	<key>queryHistory</key>
+	<array>
+		<string>rollback</string>
+		<string>begin;
+delete from tb_emp</string>
+		<string>-- 注意事项:
+-- 1. 给数据库和表命名的时候尽量使用全小写
+-- 2. 作为筛选条件的字符串是否区分大小看设置的校对规则
+drop database if exists hrs;
+create database hrs default charset utf8 collate utf8_general_ci;
+use hrs;
+drop table if exists tb_emp;
+drop table if exists tb_dept;
+-- 3. 数据库中的对象通常会用前缀加以区分
+-- table / view / index / function / procedure / trigger
+create table tb_dept
+(
+dno int not null comment '编号',
+dname varchar(10) not null comment '名称',
+dloc varchar(20) not null comment '所在地',
+primary key (dno)
+);
+-- 批量插入操作
+insert into tb_dept values 
+	(10, '会计部', '北京'),
+	(20, '研发部', '成都'),
+	(30, '销售部', '重庆'),
+	(40, '运维部', '深圳');
+create table tb_emp
+(
+eno int not null comment '员工编号',
+ename varchar(20) not null comment '员工姓名',
+job varchar(20) not null comment '员工职位',
+mgr int comment '主管编号',
+sal int not null comment '员工月薪',
+comm int comment '每月补贴',
+dno int comment '所在部门编号',
+primary key (eno)
+);
+-- 修改表添加一个列到mgr列的后面
+-- alter table tb_emp add column hiredate date after mgr;
+
+-- 修改表添加一个自参照的外键约束
+-- alter table tb_emp add constraint fk_emp_mgr foreign key (mgr) references tb_emp (eno);
+
+-- alter table tb_emp drop foreign key fk_emp_mgr;
+
+-- alter table tb_emp drop foreign key fk_emp_dno;
+
+-- restrict - 不允许操作
+-- cascade - 级联操作
+-- set null - 设置为null
+alter table tb_emp add constraint fk_emp_dno foreign key (dno) references tb_dept (dno);
+-- on delete restrict on update cascade;
+
+insert into tb_emp values 
+	(7800, '张三丰', '总裁', null, 9000, 1200, 20),
+	(2056, '乔峰', '分析师', 7800, 5000, 1500, 20),
+	(3088, '李莫愁', '设计师', 2056, 3500, 800, 20),
+	(3211, '张无忌', '程序员', 2056, 3200, null, 20),
+	(3233, '丘处机', '程序员', 2056, 3400, null, 20),
+	(3251, '张翠山', '程序员', 2056, 4000, null, 20),
+	(5566, '宋远桥', '会计师', 7800, 4000, 1000, 10),
+	(5234, '郭靖', '出纳', 5566, 2000, null, 10),
+	(3344, '黄蓉', '销售主管', 7800, 3000, 800, 30),
+	(1359, '胡一刀', '销售员', 3344, 1800, 200, 30),
+	(4466, '苗人凤', '销售员', 3344, 2500, null, 30),
+	(3244, '欧阳锋', '程序员', 3088, 3200, null, 20),
+	(3577, '杨过', '会计', 5566, 2200, null, 10),
+	(3588, '朱九真', '会计', 5566, 2500, null, 10);
+-- 查询月薪最高的员工姓名和工资 - 子查询/嵌套查询+聚合函数
+-- select ename, sal from tb_emp order by sal desc limit 1;
+select ename, sal from tb_emp where sal=(
+	select max(sal) from tb_emp
+);
+-- 查询员工的姓名和年薪((月薪+补贴)*12)
+select ename, (sal+ifnull(comm, 0))*12 as 年薪 from tb_emp order by 年薪 desc;
+-- 查询有员工的部门的编号和人数 - 分组查询+聚合函数
+select dno, count(dno) from tb_emp group by dno with rollup;
+-- 查询所有部门的名称和人数 - 子查询+连接查询(左外)
+select dname as 部门名称, ifnull(total, 0) as 人数 from tb_dept t1 left join (select dno, count(dno) as total from tb_emp group by dno) t2 on t1.dno=t2.dno;
+-- 查询月薪最高的员工(Boss除外)的姓名和工资 - 空值判断
+select ename, sal from tb_emp where sal=(select max(sal) from tb_emp where mgr is not null);
+-- 查询月薪超过平均薪水的员工的姓名和工资
+select ename, sal from tb_emp where sal&gt;(select avg(sal) as avgsal from tb_emp);
+-- 查询月薪超过其所在部门平均薪水的员工的姓名、部门编号和工资
+select ename, t1.dno, sal, round(avgsal, 2) from tb_emp t1 inner join (select dno, avg(sal) as avgsal from tb_emp group by dno) t2 on t1.dno=t2.dno where sal&gt;avgsal;
+-- 查询部门中薪水最高的人姓名、工资和所在部门名称
+select ename, sal, dname from (select ename, sal, t1.dno from tb_emp t1 inner join (select dno, max(sal) as maxsal from tb_emp group by dno) t2 on t1.dno=t2.dno where sal=maxsal) t3 inner join tb_dept t4 on t3.dno=t4.dno;
+-- 查询主管的姓名和职位
+select ename, job from tb_emp where eno in (select distinct mgr from tb_emp where mgr is not null);
+-- 通常不推荐使用in或者not in集合运算和distinct去重操作
+-- 可以考虑用exists或not exists替代掉集合运算和去重操作
+select ename, job from tb_emp t1 where exists (select 'x' from tb_emp t2 where t1.eno=t2.mgr);
+-- 查询月薪排名4~6名的员工姓名和工资
+select ename, sal from tb_emp order by sal desc limit 3, 3;
+select ename, sal from tb_emp order by sal desc limit 3 offset 3;
+-- explain生成执行计划
+explain select eno, ename from tb_emp where eno=7800;
+explain select eno, ename from tb_emp where eno&lt;&gt;7900;
+explain select eno, ename from tb_emp where ename='张三丰';
+explain select eno, ename from tb_emp where ename like '张%';
+explain select eno, ename from tb_emp where ename like '%张';
+explain select eno, ename from tb_emp where ename&lt;&gt;'张三丰';
+-- 视图:查询的快照(简化查询操作)
+-- 通过视图可以将用户的访问权限限制到某些指定的列上
+create view vw_emp_dept as 
+select eno, ename, dname from tb_emp t1 inner join tb_dept t2 on t1.dno=t2.dno;
+select ename, dname from vw_emp_dept;
+drop view vw_emp_dept;
+-- 索引(index)
+-- 索引可以加速查询所以应该在经常用于查询筛选条件的列上建立索引
+-- 索引会使用额外的存储空间而且会让增删改变得更慢(因为要更新索引)
+-- 所以不能够滥用索引
+create index idx_emp_ename on tb_emp (ename);
+drop index idx_emp_ename on tb_emp;
+-- 创建存储过程
+create procedure sp_dept_avg_sal(deptno int, out avgsal float)
+begin
+	select avg(sal) into avgsal from tb_emp where dno=deptno;
+end;
+-- 调用存储过程
+call sp_dept_avg_sal(20, @a);
+-- 通过输出参数取出部门平均工资
+select @a;
+-- 删除存储过程
+drop procedure sp_dept_avg_sal;
+create trigger tr_dept_update 
+after update on tb_dept for each row
+begin
+	update tb_emp set dno=new.dno where dno=old.dno;
+end;
+drop trigger tr_dept_update;
+-- DCL:授予权限(grant to)和召回权限(revoke from)
+create user 'hellokitty'@'%' identified by '123123';
+grant all privileges on hrs.* to 'hellokitty'@'%';
+revoke insert, delete, update on hrs.* from 'hellokitty'@'%';
+drop user 'hellokitty'@'%';
+-- 事务(transaction)- 把多个增删改的操作做成不可分割的原子性操作
+-- 要么全部都做,要么全都不做
+
+-- start transaction;
+-- begin;
+
+-- delete from tb_emp;
+
+-- commit;
+-- rollback;</string>
+		<string>-- 事务(transaction)- 把多个增删改的操作做成不可分割的原子性操作
+-- 要么全部都做,要么全都不做
+
+-- start transaction;
+-- begin;
+
+-- delete from tb_emp;
+
+-- commit;
+-- rollback;</string>
+		<string>delete from tb_emp</string>
+		<string>alter table tb_emp drop foreign key fk_emp_mgr</string>
+		<string>begin</string>
+		<string>-- 注意事项:
+-- 1. 给数据库和表命名的时候尽量使用全小写
+-- 2. 作为筛选条件的字符串是否区分大小看设置的校对规则
+drop database if exists hrs;
+create database hrs default charset utf8 collate utf8_general_ci;
+use hrs;
+drop table if exists tb_emp;
+drop table if exists tb_dept;
+-- 3. 数据库中的对象通常会用前缀加以区分
+-- table / view / index / function / procedure / trigger
+create table tb_dept
+(
+dno int not null comment '编号',
+dname varchar(10) not null comment '名称',
+dloc varchar(20) not null comment '所在地',
+primary key (dno)
+);
+-- 批量插入操作
+insert into tb_dept values 
+	(10, '会计部', '北京'),
+	(20, '研发部', '成都'),
+	(30, '销售部', '重庆'),
+	(40, '运维部', '深圳');
+create table tb_emp
+(
+eno int not null comment '员工编号',
+ename varchar(20) not null comment '员工姓名',
+job varchar(20) not null comment '员工职位',
+mgr int comment '主管编号',
+sal int not null comment '员工月薪',
+comm int comment '每月补贴',
+dno int comment '所在部门编号',
+primary key (eno)
+);
+-- 修改表添加一个列到mgr列的后面
+-- alter table tb_emp add column hiredate date after mgr;
+
+-- 修改表添加一个自参照的外键约束
+alter table tb_emp add constraint fk_emp_mgr foreign key (mgr) references tb_emp (eno);
+-- alter table tb_emp drop foreign key fk_emp_dno;
+
+-- restrict - 不允许操作
+-- cascade - 级联操作
+-- set null - 设置为null
+alter table tb_emp add constraint fk_emp_dno foreign key (dno) references tb_dept (dno);
+-- on delete restrict on update cascade;
+
+insert into tb_emp values 
+	(7800, '张三丰', '总裁', null, 9000, 1200, 20),
+	(2056, '乔峰', '分析师', 7800, 5000, 1500, 20),
+	(3088, '李莫愁', '设计师', 2056, 3500, 800, 20),
+	(3211, '张无忌', '程序员', 2056, 3200, null, 20),
+	(3233, '丘处机', '程序员', 2056, 3400, null, 20),
+	(3251, '张翠山', '程序员', 2056, 4000, null, 20),
+	(5566, '宋远桥', '会计师', 7800, 4000, 1000, 10),
+	(5234, '郭靖', '出纳', 5566, 2000, null, 10),
+	(3344, '黄蓉', '销售主管', 7800, 3000, 800, 30),
+	(1359, '胡一刀', '销售员', 3344, 1800, 200, 30),
+	(4466, '苗人凤', '销售员', 3344, 2500, null, 30),
+	(3244, '欧阳锋', '程序员', 3088, 3200, null, 20),
+	(3577, '杨过', '会计', 5566, 2200, null, 10),
+	(3588, '朱九真', '会计', 5566, 2500, null, 10);
+-- 查询月薪最高的员工姓名和工资 - 子查询/嵌套查询+聚合函数
+-- select ename, sal from tb_emp order by sal desc limit 1;
+select ename, sal from tb_emp where sal=(
+	select max(sal) from tb_emp
+);
+-- 查询员工的姓名和年薪((月薪+补贴)*12)
+select ename, (sal+ifnull(comm, 0))*12 as 年薪 from tb_emp order by 年薪 desc;
+-- 查询有员工的部门的编号和人数 - 分组查询+聚合函数
+select dno, count(dno) from tb_emp group by dno with rollup;
+-- 查询所有部门的名称和人数 - 子查询+连接查询(左外)
+select dname as 部门名称, ifnull(total, 0) as 人数 from tb_dept t1 left join (select dno, count(dno) as total from tb_emp group by dno) t2 on t1.dno=t2.dno;
+-- 查询月薪最高的员工(Boss除外)的姓名和工资 - 空值判断
+select ename, sal from tb_emp where sal=(select max(sal) from tb_emp where mgr is not null);
+-- 查询月薪超过平均薪水的员工的姓名和工资
+select ename, sal from tb_emp where sal&gt;(select avg(sal) as avgsal from tb_emp);
+-- 查询月薪超过其所在部门平均薪水的员工的姓名、部门编号和工资
+select ename, t1.dno, sal, round(avgsal, 2) from tb_emp t1 inner join (select dno, avg(sal) as avgsal from tb_emp group by dno) t2 on t1.dno=t2.dno where sal&gt;avgsal;
+-- 查询部门中薪水最高的人姓名、工资和所在部门名称
+select ename, sal, dname from (select ename, sal, t1.dno from tb_emp t1 inner join (select dno, max(sal) as maxsal from tb_emp group by dno) t2 on t1.dno=t2.dno where sal=maxsal) t3 inner join tb_dept t4 on t3.dno=t4.dno;
+-- 查询主管的姓名和职位
+select ename, job from tb_emp where eno in (select distinct mgr from tb_emp where mgr is not null);
+-- 通常不推荐使用in或者not in集合运算和distinct去重操作
+-- 可以考虑用exists或not exists替代掉集合运算和去重操作
+select ename, job from tb_emp t1 where exists (select 'x' from tb_emp t2 where t1.eno=t2.mgr);
+-- 查询月薪排名4~6名的员工姓名和工资
+select ename, sal from tb_emp order by sal desc limit 3, 3;
+select ename, sal from tb_emp order by sal desc limit 3 offset 3;
+-- explain生成执行计划
+explain select eno, ename from tb_emp where eno=7800;
+explain select eno, ename from tb_emp where eno&lt;&gt;7900;
+explain select eno, ename from tb_emp where ename='张三丰';
+explain select eno, ename from tb_emp where ename like '张%';
+explain select eno, ename from tb_emp where ename like '%张';
+explain select eno, ename from tb_emp where ename&lt;&gt;'张三丰';
+-- 视图:查询的快照(简化查询操作)
+-- 通过视图可以将用户的访问权限限制到某些指定的列上
+create view vw_emp_dept as 
+select eno, ename, dname from tb_emp t1 inner join tb_dept t2 on t1.dno=t2.dno;
+select ename, dname from vw_emp_dept;
+drop view vw_emp_dept;
+-- 索引(index)
+-- 索引可以加速查询所以应该在经常用于查询筛选条件的列上建立索引
+-- 索引会使用额外的存储空间而且会让增删改变得更慢(因为要更新索引)
+-- 所以不能够滥用索引
+create index idx_emp_ename on tb_emp (ename);
+drop index idx_emp_ename on tb_emp;
+-- 创建存储过程
+create procedure sp_dept_avg_sal(deptno int, out avgsal float)
+begin
+	select avg(sal) into avgsal from tb_emp where dno=deptno;
+end;
+-- 调用存储过程
+call sp_dept_avg_sal(20, @a);
+-- 通过输出参数取出部门平均工资
+select @a;
+-- 删除存储过程
+drop procedure sp_dept_avg_sal;
+create trigger tr_dept_update 
+after update on tb_dept for each row
+begin
+	update tb_emp set dno=new.dno where dno=old.dno;
+end;
+drop trigger tr_dept_update;
+-- DCL:授予权限(grant to)和召回权限(revoke from)
+create user 'hellokitty'@'%' identified by '123123';
+grant all privileges on hrs.* to 'hellokitty'@'%';
+revoke insert, delete, update on hrs.* from 'hellokitty'@'%';
+drop user 'hellokitty'@'%'</string>
+		<string>drop user 'hellokitty'@'%'</string>
+		<string>-- 注意事项:
+-- 1. 给数据库和表命名的时候尽量使用全小写
+-- 2. 作为筛选条件的字符串是否区分大小看设置的校对规则
+drop database if exists hrs;
+create database hrs default charset utf8 collate utf8_general_ci;
+use hrs;
+drop table if exists tb_emp;
+drop table if exists tb_dept;
+-- 3. 数据库中的对象通常会用前缀加以区分
+-- table / view / index / function / procedure / trigger
+create table tb_dept
+(
+dno int not null comment '编号',
+dname varchar(10) not null comment '名称',
+dloc varchar(20) not null comment '所在地',
+primary key (dno)
+);
+-- 批量插入操作
+insert into tb_dept values 
+	(10, '会计部', '北京'),
+	(20, '研发部', '成都'),
+	(30, '销售部', '重庆'),
+	(40, '运维部', '深圳');
+create table tb_emp
+(
+eno int not null comment '员工编号',
+ename varchar(20) not null comment '员工姓名',
+job varchar(20) not null comment '员工职位',
+mgr int comment '主管编号',
+sal int not null comment '员工月薪',
+comm int comment '每月补贴',
+dno int comment '所在部门编号',
+primary key (eno)
+);
+-- 修改表添加一个列到mgr列的后面
+-- alter table tb_emp add column hiredate date after mgr;
+
+-- 修改表添加一个自参照的外键约束
+alter table tb_emp add constraint fk_emp_mgr foreign key (mgr) references tb_emp (eno);
+-- alter table tb_emp drop foreign key fk_emp_dno;
+
+-- restrict - 不允许操作
+-- cascade - 级联操作
+-- set null - 设置为null
+alter table tb_emp add constraint fk_emp_dno foreign key (dno) references tb_dept (dno);
+-- on delete restrict on update cascade;
+
+insert into tb_emp values 
+	(7800, '张三丰', '总裁', null, 9000, 1200, 20),
+	(2056, '乔峰', '分析师', 7800, 5000, 1500, 20),
+	(3088, '李莫愁', '设计师', 2056, 3500, 800, 20),
+	(3211, '张无忌', '程序员', 2056, 3200, null, 20),
+	(3233, '丘处机', '程序员', 2056, 3400, null, 20),
+	(3251, '张翠山', '程序员', 2056, 4000, null, 20),
+	(5566, '宋远桥', '会计师', 7800, 4000, 1000, 10),
+	(5234, '郭靖', '出纳', 5566, 2000, null, 10),
+	(3344, '黄蓉', '销售主管', 7800, 3000, 800, 30),
+	(1359, '胡一刀', '销售员', 3344, 1800, 200, 30),
+	(4466, '苗人凤', '销售员', 3344, 2500, null, 30),
+	(3244, '欧阳锋', '程序员', 3088, 3200, null, 20),
+	(3577, '杨过', '会计', 5566, 2200, null, 10),
+	(3588, '朱九真', '会计', 5566, 2500, null, 10);
+-- 查询月薪最高的员工姓名和工资 - 子查询/嵌套查询+聚合函数
+-- select ename, sal from tb_emp order by sal desc limit 1;
+select ename, sal from tb_emp where sal=(
+	select max(sal) from tb_emp
+);
+-- 查询员工的姓名和年薪((月薪+补贴)*12)
+select ename, (sal+ifnull(comm, 0))*12 as 年薪 from tb_emp order by 年薪 desc;
+-- 查询有员工的部门的编号和人数 - 分组查询+聚合函数
+select dno, count(dno) from tb_emp group by dno with rollup;
+-- 查询所有部门的名称和人数 - 子查询+连接查询(左外)
+select dname as 部门名称, ifnull(total, 0) as 人数 from tb_dept t1 left join (select dno, count(dno) as total from tb_emp group by dno) t2 on t1.dno=t2.dno;
+-- 查询月薪最高的员工(Boss除外)的姓名和工资 - 空值判断
+select ename, sal from tb_emp where sal=(select max(sal) from tb_emp where mgr is not null);
+-- 查询月薪超过平均薪水的员工的姓名和工资
+select ename, sal from tb_emp where sal&gt;(select avg(sal) as avgsal from tb_emp);
+-- 查询月薪超过其所在部门平均薪水的员工的姓名、部门编号和工资
+select ename, t1.dno, sal, round(avgsal, 2) from tb_emp t1 inner join (select dno, avg(sal) as avgsal from tb_emp group by dno) t2 on t1.dno=t2.dno where sal&gt;avgsal;
+-- 查询部门中薪水最高的人姓名、工资和所在部门名称
+select ename, sal, dname from (select ename, sal, t1.dno from tb_emp t1 inner join (select dno, max(sal) as maxsal from tb_emp group by dno) t2 on t1.dno=t2.dno where sal=maxsal) t3 inner join tb_dept t4 on t3.dno=t4.dno;
+-- 查询主管的姓名和职位
+select ename, job from tb_emp where eno in (select distinct mgr from tb_emp where mgr is not null);
+-- 通常不推荐使用in或者not in集合运算和distinct去重操作
+-- 可以考虑用exists或not exists替代掉集合运算和去重操作
+select ename, job from tb_emp t1 where exists (select 'x' from tb_emp t2 where t1.eno=t2.mgr);
+-- 查询月薪排名4~6名的员工姓名和工资
+select ename, sal from tb_emp order by sal desc limit 3, 3;
+select ename, sal from tb_emp order by sal desc limit 3 offset 3;
+-- explain生成执行计划
+explain select eno, ename from tb_emp where eno=7800;
+explain select eno, ename from tb_emp where eno&lt;&gt;7900;
+explain select eno, ename from tb_emp where ename='张三丰';
+explain select eno, ename from tb_emp where ename like '张%';
+explain select eno, ename from tb_emp where ename like '%张';
+explain select eno, ename from tb_emp where ename&lt;&gt;'张三丰';
+-- 视图:查询的快照(简化查询操作)
+-- 通过视图可以将用户的访问权限限制到某些指定的列上
+create view vw_emp_dept as 
+select eno, ename, dname from tb_emp t1 inner join tb_dept t2 on t1.dno=t2.dno;
+select ename, dname from vw_emp_dept;
+drop view vw_emp_dept;
+-- 索引(index)
+-- 索引可以加速查询所以应该在经常用于查询筛选条件的列上建立索引
+-- 索引会使用额外的存储空间而且会让增删改变得更慢(因为要更新索引)
+-- 所以不能够滥用索引
+create index idx_emp_ename on tb_emp (ename);
+drop index idx_emp_ename on tb_emp;
+-- 创建存储过程
+create procedure sp_dept_avg_sal(deptno int, out avgsal float)
+begin
+	select avg(sal) into avgsal from tb_emp where dno=deptno;
+end;
+-- 调用存储过程
+call sp_dept_avg_sal(20, @a);
+-- 通过输出参数取出部门平均工资
+select @a;
+-- 删除存储过程
+drop procedure sp_dept_avg_sal;
+create trigger tr_dept_update 
+after update on tb_dept for each row
+begin
+	update tb_emp set dno=new.dno where dno=old.dno;
+end;
+drop trigger tr_dept_update;
+-- DCL:授予权限(grant to)和召回权限(revoke from)
+create user 'hellokitty'@'%' identified by '123123'</string>
+		<string>-- 注意事项:
+-- 1. 给数据库和表命名的时候尽量使用全小写
+-- 2. 作为筛选条件的字符串是否区分大小看设置的校对规则
+drop database if exists hrs;
+create database hrs default charset utf8 collate utf8_general_ci;
+use hrs;
+drop table if exists tb_emp;
+drop table if exists tb_dept;
+-- 3. 数据库中的对象通常会用前缀加以区分
+-- table / view / index / function / procedure / trigger
+create table tb_dept
+(
+dno int not null comment '编号',
+dname varchar(10) not null comment '名称',
+dloc varchar(20) not null comment '所在地',
+primary key (dno)
+);
+-- 批量插入操作
+insert into tb_dept values 
+	(10, '会计部', '北京'),
+	(20, '研发部', '成都'),
+	(30, '销售部', '重庆'),
+	(40, '运维部', '深圳');
+create table tb_emp
+(
+eno int not null comment '员工编号',
+ename varchar(20) not null comment '员工姓名',
+job varchar(20) not null comment '员工职位',
+mgr int comment '主管编号',
+sal int not null comment '员工月薪',
+comm int comment '每月补贴',
+dno int comment '所在部门编号',
+primary key (eno)
+);
+-- 修改表添加一个列到mgr列的后面
+-- alter table tb_emp add column hiredate date after mgr;
+
+-- 修改表添加一个自参照的外键约束
+alter table tb_emp add constraint fk_emp_mgr foreign key (mgr) references tb_emp (eno);
+-- alter table tb_emp drop foreign key fk_emp_dno;
+
+-- restrict - 不允许操作
+-- cascade - 级联操作
+-- set null - 设置为null
+alter table tb_emp add constraint fk_emp_dno foreign key (dno) references tb_dept (dno);
+-- on delete restrict on update cascade;
+
+insert into tb_emp values 
+	(7800, '张三丰', '总裁', null, 9000, 1200, 20),
+	(2056, '乔峰', '分析师', 7800, 5000, 1500, 20),
+	(3088, '李莫愁', '设计师', 2056, 3500, 800, 20),
+	(3211, '张无忌', '程序员', 2056, 3200, null, 20),
+	(3233, '丘处机', '程序员', 2056, 3400, null, 20),
+	(3251, '张翠山', '程序员', 2056, 4000, null, 20),
+	(5566, '宋远桥', '会计师', 7800, 4000, 1000, 10),
+	(5234, '郭靖', '出纳', 5566, 2000, null, 10),
+	(3344, '黄蓉', '销售主管', 7800, 3000, 800, 30),
+	(1359, '胡一刀', '销售员', 3344, 1800, 200, 30),
+	(4466, '苗人凤', '销售员', 3344, 2500, null, 30),
+	(3244, '欧阳锋', '程序员', 3088, 3200, null, 20),
+	(3577, '杨过', '会计', 5566, 2200, null, 10),
+	(3588, '朱九真', '会计', 5566, 2500, null, 10);
+-- 查询月薪最高的员工姓名和工资 - 子查询/嵌套查询+聚合函数
+-- select ename, sal from tb_emp order by sal desc limit 1;
+select ename, sal from tb_emp where sal=(
+	select max(sal) from tb_emp
+);
+-- 查询员工的姓名和年薪((月薪+补贴)*12)
+select ename, (sal+ifnull(comm, 0))*12 as 年薪 from tb_emp order by 年薪 desc;
+-- 查询有员工的部门的编号和人数 - 分组查询+聚合函数
+select dno, count(dno) from tb_emp group by dno with rollup;
+-- 查询所有部门的名称和人数 - 子查询+连接查询(左外)
+select dname as 部门名称, ifnull(total, 0) as 人数 from tb_dept t1 left join (select dno, count(dno) as total from tb_emp group by dno) t2 on t1.dno=t2.dno;
+-- 查询月薪最高的员工(Boss除外)的姓名和工资 - 空值判断
+select ename, sal from tb_emp where sal=(select max(sal) from tb_emp where mgr is not null);
+-- 查询月薪超过平均薪水的员工的姓名和工资
+select ename, sal from tb_emp where sal&gt;(select avg(sal) as avgsal from tb_emp);
+-- 查询月薪超过其所在部门平均薪水的员工的姓名、部门编号和工资
+select ename, t1.dno, sal, round(avgsal, 2) from tb_emp t1 inner join (select dno, avg(sal) as avgsal from tb_emp group by dno) t2 on t1.dno=t2.dno where sal&gt;avgsal;
+-- 查询部门中薪水最高的人姓名、工资和所在部门名称
+select ename, sal, dname from (select ename, sal, t1.dno from tb_emp t1 inner join (select dno, max(sal) as maxsal from tb_emp group by dno) t2 on t1.dno=t2.dno where sal=maxsal) t3 inner join tb_dept t4 on t3.dno=t4.dno;
+-- 查询主管的姓名和职位
+select ename, job from tb_emp where eno in (select distinct mgr from tb_emp where mgr is not null);
+-- 通常不推荐使用in或者not in集合运算和distinct去重操作
+-- 可以考虑用exists或not exists替代掉集合运算和去重操作
+select ename, job from tb_emp t1 where exists (select 'x' from tb_emp t2 where t1.eno=t2.mgr);
+-- 查询月薪排名4~6名的员工姓名和工资
+select ename, sal from tb_emp order by sal desc limit 3, 3;
+select ename, sal from tb_emp order by sal desc limit 3 offset 3;
+-- explain生成执行计划
+explain select eno, ename from tb_emp where eno=7800;
+explain select eno, ename from tb_emp where eno&lt;&gt;7900;
+explain select eno, ename from tb_emp where ename='张三丰';
+explain select eno, ename from tb_emp where ename like '张%';
+explain select eno, ename from tb_emp where ename like '%张';
+explain select eno, ename from tb_emp where ename&lt;&gt;'张三丰';
+-- 视图:查询的快照(简化查询操作)
+-- 通过视图可以将用户的访问权限限制到某些指定的列上
+create view vw_emp_dept as 
+select eno, ename, dname from tb_emp t1 inner join tb_dept t2 on t1.dno=t2.dno;
+select ename, dname from vw_emp_dept;
+drop view vw_emp_dept;
+-- 索引(index)
+-- 索引可以加速查询所以应该在经常用于查询筛选条件的列上建立索引
+-- 索引会使用额外的存储空间而且会让增删改变得更慢(因为要更新索引)
+-- 所以不能够滥用索引
+create index idx_emp_ename on tb_emp (ename);
+drop index idx_emp_ename on tb_emp;
+-- 创建存储过程
+create procedure sp_dept_avg_sal(deptno int, out avgsal float)
+begin
+	select avg(sal) into avgsal from tb_emp where dno=deptno;
+end;
+-- 调用存储过程
+call sp_dept_avg_sal(20, @a);
+-- 通过输出参数取出部门平均工资
+select @a;
+-- 删除存储过程
+drop procedure sp_dept_avg_sal;
+-- 触发器:在执行增删改操作时可以触发其他的级联操作,但是有可能导致“锁表”现象,实际开发中应该尽量避免使用触发器
+update tb_dept set dno=11 where dno=10</string>
+		<string>-- 注意事项:
+-- 1. 给数据库和表命名的时候尽量使用全小写
+-- 2. 作为筛选条件的字符串是否区分大小看设置的校对规则
+drop database if exists hrs;
+create database hrs default charset utf8 collate utf8_general_ci;
+use hrs;
+drop table if exists tb_emp;
+drop table if exists tb_dept;
+-- 3. 数据库中的对象通常会用前缀加以区分
+-- table / view / index / function / procedure / trigger
+create table tb_dept
+(
+dno int not null comment '编号',
+dname varchar(10) not null comment '名称',
+dloc varchar(20) not null comment '所在地',
+primary key (dno)
+);
+-- 批量插入操作
+insert into tb_dept values 
+	(10, '会计部', '北京'),
+	(20, '研发部', '成都'),
+	(30, '销售部', '重庆'),
+	(40, '运维部', '深圳');
+create table tb_emp
+(
+eno int not null comment '员工编号',
+ename varchar(20) not null comment '员工姓名',
+job varchar(20) not null comment '员工职位',
+mgr int comment '主管编号',
+sal int not null comment '员工月薪',
+comm int comment '每月补贴',
+dno int comment '所在部门编号',
+primary key (eno)
+);
+-- 修改表添加一个列到mgr列的后面
+-- alter table tb_emp add column hiredate date after mgr;
+
+-- 修改表添加一个自参照的外键约束
+alter table tb_emp add constraint fk_emp_mgr foreign key (mgr) references tb_emp (eno);
+alter table tb_emp drop foreign key fk_emp_dno</string>
+		<string>revoke insert, delete, update on hrs.* from 'hellokitty'@'%'</string>
+		<string>grant all privileges on hrs.* to 'hellokitty'@'%'</string>
+		<string>-- DCL:授予权限(grant to)和召回权限(revoke from)
+create user 'hellokitty'@'%' identified by '123123'</string>
+		<string>delete from tb_dept where dno=11</string>
+		<string>update tb_dept set dno=11 where dno=10</string>
+		<string>alter table tb_emp add constraint fk_emp_dno foreign key (dno) references tb_dept (dno) on delete cascade on update cascade</string>
+		<string>alter table tb_emp drop foreign key fk_emp_dno</string>
+		<string>delete from tb_dept where dno=10</string>
+	</array>
+	<key>rdbms_type</key>
+	<string>mysql</string>
+	<key>rdbms_version</key>
+	<string>5.5.60-MariaDB</string>
+	<key>version</key>
+	<integer>1</integer>
+</dict>
+</plist>

+ 376 - 0
Day36-40/code/学校选课系统.spf

@@ -0,0 +1,376 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+	<key>ContentFilters</key>
+	<dict/>
+	<key>auto_connect</key>
+	<true/>
+	<key>data</key>
+	<dict>
+		<key>connection</key>
+		<dict>
+			<key>database</key>
+			<string>school</string>
+			<key>host</key>
+			<string>120.77.222.217</string>
+			<key>kcid</key>
+			<string>6157604644212181126</string>
+			<key>name</key>
+			<string>MySQL@Aliyun</string>
+			<key>rdbms_type</key>
+			<string>mysql</string>
+			<key>sslCACertFileLocation</key>
+			<string></string>
+			<key>sslCACertFileLocationEnabled</key>
+			<integer>0</integer>
+			<key>sslCertificateFileLocation</key>
+			<string></string>
+			<key>sslCertificateFileLocationEnabled</key>
+			<integer>0</integer>
+			<key>sslKeyFileLocation</key>
+			<string></string>
+			<key>sslKeyFileLocationEnabled</key>
+			<integer>0</integer>
+			<key>type</key>
+			<string>SPTCPIPConnection</string>
+			<key>useSSL</key>
+			<integer>0</integer>
+			<key>user</key>
+			<string>root</string>
+		</dict>
+		<key>session</key>
+		<dict>
+			<key>connectionEncoding</key>
+			<string>utf8</string>
+			<key>contentPageNumber</key>
+			<integer>1</integer>
+			<key>contentSelection</key>
+			<data>
+			YnBsaXN0MDDUAQIDBAUGOTpYJHZlcnNpb25YJG9iamVjdHNZJGFy
+			Y2hpdmVyVCR0b3ASAAGGoK0HCBUWFxgZHSQoLDE2VSRudWxs0wkK
+			CwwQFFdOUy5rZXlzWk5TLm9iamVjdHNWJGNsYXNzow0OD4ACgAOA
+			BKMREhOABYAGgAiADFR0eXBlVHJvd3NUa2V5c18QJlNlbGVjdGlv
+			bkRldGFpbFR5cGVQcmltYXJ5S2V5ZWREZXRhaWxz0wkKCxobHKCg
+			gAfSHh8gIVokY2xhc3NuYW1lWCRjbGFzc2VzXxATTlNNdXRhYmxl
+			RGljdGlvbmFyeaMgIiNcTlNEaWN0aW9uYXJ5WE5TT2JqZWN00goL
+			JSehJoAJgAvSCykqK1lOUy5zdHJpbmeAClRzY2lk0h4fLS5fEA9O
+			U011dGFibGVTdHJpbmejLS8wWE5TU3RyaW5nWE5TT2JqZWN00h4f
+			MjNeTlNNdXRhYmxlQXJyYXmjMjQ1V05TQXJyYXlYTlNPYmplY3TS
+			Hh8iN6IiOFhOU09iamVjdF8QD05TS2V5ZWRBcmNoaXZlctE7PFRk
+			YXRhgAEACAARABoAIwAtADIANwBFAEsAUgBaAGUAbABwAHIAdAB2
+			AHoAfAB+AIAAggCHAIwAkQC6AMEAwgDDAMUAygDVAN4A9AD4AQUB
+			DgETARUBFwEZAR4BKAEqAS8BNAFGAUoBUwFcAWEBcAF0AXwBhQGK
+			AY0BlgGoAasBsAAAAAAAAAIBAAAAAAAAAD0AAAAAAAAAAAAAAAAA
+			AAGy
+			</data>
+			<key>contentSortColIsAsc</key>
+			<true/>
+			<key>contentViewport</key>
+			<string>{{0, 0}, {694, 448}}</string>
+			<key>isToolbarVisible</key>
+			<true/>
+			<key>queries</key>
+			<string>-- 如果存在名为school的数据库就删除它
+drop database if exists school;
+
+-- 创建名为school的数据库并设置默认的字符集和排序方式
+create database school default charset utf8 collate utf8_bin;
+
+-- 切换到school数据库上下文环境
+use school;
+
+-- 创建学院表
+create table tb_college
+(
+collid int not null auto_increment comment '编号',
+collname varchar(50) not null comment '名称',
+collmaster varchar(20) not null comment '院长',
+collweb varchar(511) default '' comment '网站',
+primary key (collid)
+);
+
+-- 创建学生表
+create table tb_student
+(
+stuid int not null comment '学号',
+stuname varchar(20) not null comment '姓名',
+stusex bit default 1 comment '性别',
+stubirth date not null comment '出生日期',
+stuaddr varchar(255) default '' comment '籍贯',
+collid int not null comment '所属学院',
+primary key (stuid),
+foreign key (collid) references tb_college (collid)
+);
+
+-- alter table tb_student add constraint fk_student_collid foreign key (collid) references tb_college (collid);
+
+-- 创建教师表
+create table tb_teacher
+(
+teaid int not null comment '工号',
+teaname varchar(20) not null comment '姓名',
+teatitle varchar(10) default '助教' comment '职称',
+collid int not null comment '所属学院',
+primary key (teaid),
+foreign key (collid) references tb_college (collid)
+);
+
+-- 创建课程表
+create table tb_course
+(
+couid int not null comment '编号',
+couname varchar(50) not null comment '名称',
+coucredit int not null comment '学分',
+teaid int not null comment '授课老师',
+primary key (couid),
+foreign key (teaid) references tb_teacher (teaid)
+);
+
+-- 创建选课记录表
+create table tb_score
+(
+scid int auto_increment comment '选课记录编号',
+stuid int not null comment '选课学生',
+couid int not null comment '所选课程',
+scdate datetime comment '选课时间日期',
+scmark decimal(4,1) comment '考试成绩',
+primary key (scid),
+foreign key (stuid) references tb_student (stuid),
+foreign key (couid) references tb_course (couid)
+);
+
+-- 添加唯一性约束(一个学生选某个课程只能选一次)
+alter table tb_score add constraint uni_score_stuid_couid unique (stuid, couid);
+
+-- 插入学院数据
+insert into tb_college (collname, collmaster, collweb) values 
+('计算机学院', '左冷禅', 'http://www.abc.com'),
+('外国语学院', '岳不群', 'http://www.xyz.com'),
+('经济管理学院', '风清扬', 'http://www.foo.com');
+
+-- 插入学生数据
+insert into tb_student (stuid, stuname, stusex, stubirth, stuaddr, collid) values
+(1001, '杨逍', 1, '1990-3-4', '四川成都', 1),
+(1002, '任我行', 1, '1992-2-2', '湖南长沙', 1),
+(1033, '王语嫣', 0, '1989-12-3', '四川成都', 1),
+(1572, '岳不群', 1, '1993-7-19', '陕西咸阳', 1),
+(1378, '纪嫣然', 0, '1995-8-12', '四川绵阳', 1),
+(1954, '林平之', 1, '1994-9-20', '福建莆田', 1),
+(2035, '东方不败', 1, '1988-6-30', null, 2),
+(3011, '林震南', 1, '1985-12-12', '福建莆田', 3),
+(3755, '项少龙', 1, '1993-1-25', null, 3),
+(3923, '杨不悔', 0, '1985-4-17', '四川成都', 3);
+
+-- 插入老师数据
+insert into tb_teacher (teaid, teaname, teatitle, collid) values 
+(1122, '张三丰', '教授', 1),
+(1133, '宋远桥', '副教授', 1),
+(1144, '杨逍', '副教授', 1),
+(2255, '范遥', '副教授', 2),
+(3366, '韦一笑', '讲师', 3);
+
+-- 插入课程数据
+insert into tb_course (couid, couname, coucredit, teaid) values 
+(1111, 'Python程序设计', 3, 1122),
+(2222, 'Web前端开发', 2, 1122),
+(3333, '操作系统', 4, 1122),
+(4444, '计算机网络', 2, 1133),
+(5555, '编译原理', 4, 1144),
+(6666, '算法和数据结构', 3, 1144),
+(7777, '经贸法语', 3, 2255),
+(8888, '成本会计', 2, 3366),
+(9999, '审计学', 3, 3366);
+
+-- 插入选课数据
+insert into tb_score (stuid, couid, scdate, scmark) values 
+(1001, 1111, '2017-09-01', 95),
+(1001, 2222, '2017-09-01', 87.5),
+(1001, 3333, '2017-09-01', 100),
+(1001, 4444, '2018-09-03', null),
+(1001, 6666, '2017-09-02', 100),
+(1002, 1111, '2017-09-03', 65),
+(1002, 5555, '2017-09-01', 42),
+(1033, 1111, '2017-09-03', 92.5),
+(1033, 4444, '2017-09-01', 78),
+(1033, 5555, '2017-09-01', 82.5),
+(1572, 1111, '2017-09-02', 78),
+(1378, 1111, '2017-09-05', 82),
+(1378, 7777, '2017-09-02', 65.5),
+(2035, 7777, '2018-09-03', 88),
+(2035, 9999, curdate(), null),
+(3755, 1111, date(now()), null),
+(3755, 8888, date(now()), null),
+(3755, 9999, '2017-09-01', 92);
+
+-- 查询所有学生信息
+select * from tb_student;
+
+-- 查询所有课程名称及学分(投影和别名)
+select couname, coucredit from tb_course;
+select couname as 课程名称, coucredit as 学分 from tb_course;
+
+select stuname as 姓名, case stusex when 1 then '男' else '女' end as 性别 from tb_student;
+select stuname as 姓名, if(stusex, '男', '女') as 性别 from tb_student;
+
+-- 查询所有女学生的姓名和出生日期(筛选)
+select stuname, stubirth from tb_student where stusex=0;
+
+-- 查询所有80后学生的姓名、性别和出生日期(筛选)
+select stuname, stusex, stubirth from tb_student where stubirth&gt;='1980-1-1' and stubirth&lt;='1989-12-31';
+select stuname, stusex, stubirth from tb_student where stubirth between '1980-1-1' and '1989-12-31';
+
+-- 查询姓"杨"的学生姓名和性别(模糊)
+select stuname, stusex from tb_student where stuname like '杨%';
+
+-- 查询姓"杨"名字两个字的学生姓名和性别(模糊)
+select stuname, stusex from tb_student where stuname like '杨_';
+
+-- 查询姓"杨"名字三个字的学生姓名和性别(模糊)
+select stuname, stusex from tb_student where stuname like '杨__';
+
+-- 查询名字中有"不"字或"嫣"字的学生的姓名(模糊)
+select stuname, stusex from tb_student where stuname like '%不%' or stuname like '%嫣%';
+
+-- 查询没有录入家庭住址的学生姓名(空值)
+select stuname from tb_student where stuaddr is null;
+
+-- 查询录入了家庭住址的学生姓名(空值)
+select stuname from tb_student where stuaddr is not null;
+
+-- 查询学生选课的所有日期(去重)
+select distinct scdate from tb_score;
+
+-- 查询学生的家庭住址(去重)
+select distinct stuaddr from tb_student where stuaddr is not null;
+
+-- 查询男学生的姓名和生日按年龄从大到小排列(排序)
+-- asc - ascending - 升序(从小到大)
+-- desc - descending - 降序(从大到小)
+select stuname as 姓名, year(now())-year(stubirth) as 年龄 from tb_student where stusex=1 order by 年龄 desc;
+
+-- 聚合函数:max / min / count / sum / avg
+-- 查询年龄最大的学生的出生日期(聚合函数)
+select min(stubirth) from tb_student;
+
+-- 查询年龄最小的学生的出生日期(聚合函数)
+select max(stubirth) from tb_student;
+
+-- 查询男女学生的人数(分组和聚合函数)
+select count(stuid) from tb_student;
+select stusex, count(*) from tb_student group by stusex;
+select stusex, min(stubirth) from tb_student group by stusex;
+
+-- 查询课程编号为1111的课程的平均成绩(筛选和聚合函数)
+select avg(scmark) from tb_score where couid=1111;
+select min(scmark) from tb_score where couid=1111;
+select count(scid) from tb_score where couid=1111;
+select count(scmark) from tb_score where couid=1111;
+
+-- 查询学号为1001的学生所有课程的平均分(筛选和聚合函数)
+select avg(scmark) from tb_score where stuid=1001;
+
+-- 查询每个学生的学号和平均成绩(分组和聚合函数)
+select stuid as 学号, avg(scmark) as 平均分 from tb_score group by stuid;
+
+-- 查询平均成绩大于等于90分的学生的学号和平均成绩
+-- 分组以前的筛选使用where子句
+-- 分组以后的筛选使用having子句
+select stuid as 学号, avg(scmark) as 平均分 from tb_score group by stuid having 平均分&gt;=90;
+
+-- 查询年龄最大的学生的姓名(子查询/嵌套的查询)
+select stuname from tb_student where stubirth=(
+	select min(stubirth) from tb_student
+);
+
+-- 查询年龄最大的学生姓名和年龄(子查询+运算)
+select stuname as 姓名, year(now())-year(stubirth) as 年龄 from tb_student where stubirth=(
+	select min(stubirth) from tb_student
+);
+
+-- 查询选了两门以上的课程的学生姓名(子查询/分组条件/集合运算)
+select stuname from tb_student where stuid=(
+	select stuid from tb_score group by stuid having count(stuid)&gt;2
+)
+
+-- 查询学生姓名、课程名称以及成绩(连接查询)
+select stuname, couname, scmark from tb_student t1, tb_course t2, tb_score t3 where t1.stuid=t3.stuid and t2.couid=t3.couid and scmark is not null;
+
+select stuname, couname, scmark from tb_student t1 inner join tb_score t3 on t1.stuid=t3.stuid inner join tb_course t2 on t2.couid=t3.couid where scmark is not null order by scmark desc limit 5 offset 10;
+
+select stuname, couname, scmark from tb_student t1 inner join tb_score t3 on t1.stuid=t3.stuid inner join tb_course t2 on t2.couid=t3.couid where scmark is not null order by scmark desc limit 10, 5;
+
+-- 单表:65535TB
+-- 单列:4G - LONGBLOB (Binary Large OBject) / LONGTEXT
+-- 查询选课学生的姓名和平均成绩(子查询和连接查询)
+select stuname, avgmark from tb_student t1, (select stuid, avg(scmark) as avgmark from tb_score group by stuid) t2 where t1.stuid=t2.stuid;
+
+select stuname, avgmark from tb_student t1 inner join 
+(select stuid, avg(scmark) as avgmark from tb_score group by stuid) t2 on t1.stuid=t2.stuid;
+
+-- 内连接(inner join):只有满足连接条件的记录才会被查出来
+-- 外连接(outer join):左外连接 / 右外连接 / 全外连接
+-- left outer join / right outer join / full outer join
+-- 查询每个学生的姓名和选课数量(左外连接和子查询)
+select stuname, ifnull(total, 0) from tb_student t1 left outer join (select stuid, count(stuid) as total from tb_score group by stuid) t2 on t1.stuid=t2.stuid;
+</string>
+			<key>table</key>
+			<string>tb_score</string>
+			<key>view</key>
+			<string>SP_VIEW_CUSTOMQUERY</string>
+			<key>windowVerticalDividerPosition</key>
+			<real>163</real>
+		</dict>
+	</dict>
+	<key>encrypted</key>
+	<false/>
+	<key>format</key>
+	<string>connection</string>
+	<key>queryFavorites</key>
+	<array/>
+	<key>queryHistory</key>
+	<array>
+		<string>select stuname, couname, scmark from tb_student t1 inner join tb_score t3 on t1.stuid=t3.stuid inner join tb_course t2 on t2.couid=t3.couid where scmark is not null order by scmark desc limit 5 offset 10</string>
+		<string>select stuname, couname, scmark from tb_student t1 inner join tb_score t3 on t1.stuid=t3.stuid inner join tb_course t2 on t2.couid=t3.couid where scmark is not null order by scmark desc limit 10, 5</string>
+		<string>select stuname, couname, scmark from tb_student t1 inner join tb_score t3 on t1.stuid=t3.stuid inner join tb_course t2 on t2.couid=t3.couid where scmark is not null order by scmark desc limit 5, 5</string>
+		<string>select stuname, couname, scmark from tb_student t1 inner join tb_score t3 on t1.stuid=t3.stuid inner join tb_course t2 on t2.couid=t3.couid where scmark is not null order by scmark desc limit 50, 5</string>
+		<string>select stuname, couname, scmark from tb_student t1 inner join tb_score t3 on t1.stuid=t3.stuid inner join tb_course t2 on t2.couid=t3.couid where scmark is not null order by scmark desc limit 5 offset 5</string>
+		<string>select stuname, couname, scmark from tb_student t1 inner join tb_score t3 on t1.stuid=t3.stuid inner join tb_course t2 on t2.couid=t3.couid where scmark is not null order by scmark desc limit 5</string>
+		<string>select stuname, couname, scmark from tb_student t1 inner join tb_score t3 on t1.stuid=t3.stuid inner join tb_course t2 on t2.couid=t3.couid where scmark is not null order by scmark desc</string>
+		<string>select stuname, couname, scmark from tb_student t1 inner join tb_score t3 on t1.stuid=t3.stuid inner join tb_course t2 on t2.couid=t3.couid where scmark is not null</string>
+		<string>select stuname, couname, scmark from tb_student t1, tb_course t2, tb_score t3 where t1.stuid=t3.stuid and t2.couid=t3.couid and scmark is not null</string>
+		<string>select stuname, couname, scmark from tb_student t1, tb_course t2, tb_score t3 where t1.stuid=t3.stuid and t2.couid=t3.couid where scmark is not null</string>
+		<string>-- 查询学生姓名、课程名称以及成绩(连接查询)
+select stuname, couname, scmark from tb_student t1, tb_course t2, tb_score t3 where t1.stuid=t3.stuid and t2.couid=t3.couid where scmark is not null</string>
+		<string>select stuname, avgmark from tb_student t1 inner join 
+(select stuid, avg(scmark) as avgmark from tb_score group by stuid) t2 on t1.stuid=t2.stuid</string>
+		<string>select stuname, avgmark from tb_student t1, (select stuid, avg(scmark) as avgmark from tb_score group by stuid) t2 where t1.stuid=t2.stuid</string>
+		<string>select stuname, ifnull(total, 0) from tb_student t1 left outer join (select stuid, count(stuid) as total from tb_score group by stuid) t2 on t1.stuid=t2.stuid</string>
+		<string>select stuname, ifnull(total,0) from tb_student t1 left outer join (select stuid, count(stuid) as total from tb_score group by stuid) t2 on t1.stuid=t2.stuid</string>
+		<string>-- 查询选了两门以上的课程的学生姓名(子查询/分组条件/集合运算)
+select stuname from tb_student where stuid=(
+	select stuid from tb_score group by stuid having count(stuid)&gt;2
+)
+
+-- 查询学生姓名、课程名称以及成绩(连接查询)
+
+-- 查询选课学生的姓名和平均成绩(子查询和连接查询)
+
+-- 外连接(outer join):左外连接 / 右外连接 / 全外连接
+-- 查询每个学生的姓名和选课数量(左外连接和子查询)
+select stuname, ifnull(total, 0) from tb_student t1 left outer join (select stuid, count(stuid) as total from tb_score group by stuid) t2 on t1.stuid=t2.stuid</string>
+		<string>select stuname, total from tb_student t1 left outer join 
+(select stuid, count(stuid) as total from tb_score group by stuid) t2 on t1.stuid=t2.stuid</string>
+		<string>select stuname, total from tb_student t1 inner join 
+(select stuid, count(stuid) as total from tb_score group by stuid) t2 on t1.stuid=t2.stuid</string>
+		<string>select stuid, count(stuid) from tb_score group by stuid</string>
+		<string>select stuname, couname, scmark from tb_student t1 inner join tb_score t3 on t1.stuid=t3.stuid inner join tb_course t2 on t2.couid=t3.couid</string>
+	</array>
+	<key>rdbms_type</key>
+	<string>mysql</string>
+	<key>rdbms_version</key>
+	<string>5.5.60-MariaDB</string>
+	<key>version</key>
+	<integer>1</integer>
+</dict>
+</plist>

+ 10 - 4
Day36-40/关系型数据库MySQL.md

@@ -4,7 +4,7 @@
 
 1. 数据持久化 - 将数据保存到(在掉电情况下)能够长久保存数据的存储介质中。
 
-2. 数据库发展史 - 网状数据库、层次数据库、关系数据库。
+2. 数据库发展史 - 网状数据库、层次数据库、关系数据库、NoSQL数据库
 
    > 1970年,IBM的研究员E.F.Codd在*Communication of the ACM*上发表了名为*A Relational Model of Data for Large Shared Data Banks*的论文,提出了关系模型的概念,奠定了关系模型的理论基础。后来Codd又陆续发表多篇文章,论述了范式理论和衡量关系系统的12条标准,用数学理论奠定了关系数据库的基础。
 
@@ -31,9 +31,11 @@
 
 ### MySQL简介
 
-1. 安装和配置。
+1. 安装和配置(以Linux环境为例)。
+
 2. 常用命令。
 
+
 ### SQL详解
 
 1. DDL
@@ -315,6 +317,10 @@
 
 #### 范式理论
 
+1. 第一范式
+2. 第二范式
+3. 第三范式
+
 #### 数据完整性
 
 1. 实体完整性 - 每个实体都是独一无二的
@@ -416,9 +422,9 @@ insert into tb_emp values
                    (no, name, loc)
                )
            if result == 1:
-               # 4. 操作成功提交事务
-               con.commit()
                print('添加成功!')
+           # 4. 操作成功提交事务
+           con.commit()
        finally:
            # 5. 关闭连接释放资源
            con.close()