这篇博客记录一下博主第一次学MySQL,博主跟着B站518编程up主《一天学完MySQL》视频学的,从建表,查询,到事务,up讲的清晰明了干脆层次感非常不错,在此感谢。下面是我的笔记,提醒自己好好学习数据库。
show databases;
create database test;
use test;
create table student(
sno varchar(20) primary key,
sname varchar(20) not null,
ssex varchar(10) not null,
sbirthday datetime,
class varchar(20)
);
create table teacher(
tno varchar(20) primary key,
tname varchar(20) not null,
tsex varchar(10) not null,
tbirthday datetime,
prof varchar(20) not null,
depart varchar(20) not null
);
create table course(
cno varchar(20) primary key,
cname varchar(20) not null,
tno varchar(20) not null,
foreign key(tno) references teacher(tno)
);
create table score(
sno varchar(20) primary key,
cno varchar(20) not null,
degree decimal,
foreign key(sno) references student(sno),
foreign key(cno) references course(cno)
);
show tables;
insert into student values('101', '曾华', '男', '1977-09-01', '95033');
insert into student values('102', '匡明', '男', '1975-10-02', '95031');
insert into student values('103', '王丽', '女', '1976-01-23', '95033');
insert into student values('104', '李军', '男', '1976-02-20', '95033');
insert into student values('105', '王芳', '女', '1975-02-10', '95031');
insert into student values('106', '陆君', '男', '1974-06-03', '95031');
insert into student values('107', '王尼玛', '男', '1976-02-20', '95033');
insert into student values('108', '张全蛋', '男', '1975-02-10', '95031');
insert into student values('109', '赵铁柱', '男', '1974-06-03', '95031');
insert into student values('110', '赵飞', '男', '1974-06-03', '95038');
create table score(
sno varchar(20) not null,
cno varchar(20) not null,
degree decimal,
foreign key(sno) references student(sno),
foreign key(cno) references course(cno),
primary key(sno, cno)
);
insert into teacher values('804','李诚', '男', '1958-12-02', '副教授', '计算机系');
insert into teacher values('856','张旭', '男', '1969-03-12', '讲师', '电子工程系');
insert into teacher values('825','王萍', '女', '1972-05-05', '助教', '计算机系');
insert into teacher values('831','刘冰', '女', '1977-08-14', '助教', '电子工程系');
insert into course values('3-105', '计算机导论', '825');
insert into course values('3-245', '操作系统', '804');
insert into course values('6-166', '数字电路', '856');
insert into course values('9-888', '高等数学', '831');
insert into score values('103', '3-245', '86');
insert into score values('105', '3-245', '75');
insert into score values('109', '3-245', '68');
insert into score values('103', '3-105', '92');
insert into score values('105', '3-105', '88');
insert into score values('109', '3-105', '76');
insert into score values('103', '6-166', '85');
insert into score values('105', '6-166', '79');
insert into score values('109', '6-166', '81');
insert into score values('101', '3-105', '90');
insert into score values('102', '3-105', '91');
insert into score values('104', '3-105', '89');
show tables;
select * from student; #查询student所有记录
select sname, ssex, class from student; #查询student表的姓名,性别,班级字段
select distinct depart from teacher; #查询所欲老师所在的单位,即不重复的depart列
select * from score where degree between 60 and 80; #查询score表成绩在60到80之间的所有记录
select * from score where degree > 60 and degree < 80; #查询score表成绩在60到80之间的所有记录
select * from score where degree in (85, 86, 88); #查询score成绩为85,86或88的记录
select * from student where class='95031' or ssex='女'; #查询student表95031班或性别为女的同学记录
select * from student order by class desc; #以class降序查询student表的所有记录
select * from score order by cno asc, degree desc; #以cno升序,degree降序查询score表的所有记录
select count(*) from student where class='95031'; #查询95031班的学生人数
select sno, cno from score where degree=(select max(degree) from score); #查询score表中最高分的学生学号和课程号
select max(degree) from score;
select sno, cno from score where degree = (select max(degree) from score);
select sno, cno from score order by degree desc limit 0,1; #按排序找出最高分的,无法排除最高分多个的记录
select avg(degree) from score group by cno; #查询每门课的平均成绩
select sno, cname, degree from course, score where course.cno =score.cno; #查询所有学生的sno,cname, degree列
select a.sno, b.cname, a.degree from score a inner join course b on b.cno=a.cno;
select sname, cno, degree from student, score where student.sno=score.sno; #查询所有学生的sname, cno, degree列
select a.sname, b.cno, b.degree from student a inner join score b on b.sno=a.sno; #查询所有学生的sname, cno, degree列
select sname, cname, degree from student, course, score
where student.sno=score.sno and course.cno=score.cno; #查询所有学生的sname, cname, degree
select a.sname, c.cname, b.degree from student a
inner join score b on b.sno=a.sno
inner join course c on c.cno=b.cno; #查询所有学生的sname, cname, degree
select * from student where class='95031'; #查询95031班的学生每门课的平均成绩
select cno, avg(degree)
from score
where sno in (select sno from student where class='95031') group by cno; #查询95031班的学生每门课的平均成绩
select degree from score where sno='109' and cno='3-105';
select * from score
where cno = '3-105'
and degree>(select degree from score where sno='109' and cno='3-105');#查询选修3-105课程的成绩高于109号同学3-105成绩的所有同学记录
select * from score
where degree>(select degree from score where sno='109' and cno='3-105'); #查询成绩高于学号为109,课程号为3-105的成绩的所有记录
select year(sbirthday) from student where sno in (101, 108);
select sno, sname, sbirthday from student
where year(sbirthday) in (select year(sbirthday) from student where sno in ('101', '108')); #查询和学号为108,101的同学同年出生的所有学生的sno,sname和sbirthday列
select tno from teacher where tname='张旭';
select cno from course where tno=(select tno from teacher where tname='张旭');
select * from score
where cno=(select cno from course where tno=(select tno from teacher where tname='张旭')); #查询‘张旭’老师任课的学生成绩
select cno from score group by cno having count(*)>5;
select tno from course where cno=(select cno from score group by cno having count(*)>5);
select tname
from teacher
where tno=(select tno from course where cno=(select cno from score group by cno having count(*)>5)); #查询选修某课程的同学人数多于5人的教师姓名
select * from student where class in (95033, 95031); #查询班级为950322,95031所有学生信息
select cno from score where degree>85; #查询存在有85分以上的成绩的课程cno
select tno from teacher where depart='计算机系';
select cno from course where tno in (select tno from teacher where depart='计算机系');
select * from score
where cno in (select cno from course where tno in (select tno from teacher where depart='计算机系')); #查询计算机系 教师所教课程的成绩表
select tname, prof
from teacher
where depart='计算机系' and prof not in(select prof from teacher where depart='电子工程系')
union
select tname, prof
from teacher
where depart='电子工程系' and prof not in(select prof from teacher where depart='计算机系'); #查询计算机系和电子工程系不同职称的教师的tname和prof
select cno, sno, degree
from score
where cno='3-105' and degree>any(select degree from score where cno='3-245')
order by degree desc; # 查询选修编号为3-105课程且成绩至少高于选修编号为3-245的同学的cno, sno和degree
select cno, sno, degree
from score
where cno='3-105' and degree>(select degree from score where cno='3-245' order by degree limit 1)
order by degree desc; # 查询选修编号为3-105课程且成绩至少高于选修编号为3-245的同学的cno, sno和degree
select cno, sno, degree
from score
where cno='3-105' and degree>all(select degree from score where cno='3-245'); # 查询选修编号为3-105课程且成绩高于选修编号为3-245的同学的cno, sno和degree
select tname as name, tsex as sex, tbirthday as birthday from teacher
union
select sname, ssex, sbirthday from student; #查询所有老师,学生的姓名,性别和生日
select tname as name, tsex as sex, tbirthday as birthday from teacher where tsex='女'
union
select sname, ssex, sbirthday from student where ssex='女'; #查询所有女老师,女学生的姓名,性别和生日
select cno, avg(degree) from score group by cno;
select * from score a
where degree<(select avg(degree) from score b where a.cno=b.cno); #查询成绩比该课程平均成绩低的同学的成绩表
select tname, depart from teacher where tno in (select tno from course); #查询所有任课老师的tname,depart
select class from student where ssex='男' group by class having count(*)>=2; #查询至少2名男生的班号
select * from student where sname not like '王%'; #查询student表中不姓王的同学alter
select sname, year(now())-year(sbirthday) as age from student; #查询所有学生的姓名和年龄
select max(sbirthday), min(sbirthday) from student; #查询student表中最大和最小的sbirthdday日期值
select * from student order by class desc, year(now())-year(sbirthday) desc; #以班号和年龄从大到小的顺序查询student表中的全部记录
select * from teacher where tsex='男';
select * from course where tno in (select tno from teacher where tsex='男'); #查询所有男老师所上的课程
select max(degree) from score; #查询最高分同学的sno,cno和degree
select sno, cno, degree from score where degree =(select max(degree) from score); #查询最高分同学的sno,cno和degree
select sname from student where ssex=(select ssex from student where sname='李军'); #查询和李军同性别的所有同学的sname
select ssex, class from student where sname='李军';
select sname from student
where ssex=(select ssex from student where sname='李军')
and class=(select class from student where sname='李军'); #查询和李军同性别同班的同学sname
select * from student where ssex='男';
select * from course where cname='计算机导论';
select * from score
where cno=(select cno from course where cname='计算机导论')
and sno in (select sno from student where ssex='男'); #查询所有选修计算机导论课程的男同学的成绩表
create table grade(
low int(3),
upp int(3),
grade char(1)
);
insert into grade values(90, 100, 'A');
insert into grade values(80, 89, 'B');
insert into grade values(70, 79, 'C');
insert into grade values(60, 69, 'D');
insert into grade values(0, 59, 'E');
select sno, cno, grade from score, grade
where degree between low and upp; #查询所有同学的sno,cno和grade列
create database testjoin;
use testjoin;
create table person(
id int,
name varchar(20),
cardId int
);
create table card(
id int,
name varchar(20)
);
insert into card values(1, '饭卡');
insert into card values(2, '建行卡');
insert into card values(3, '农行卡');
insert into card values(4, '工商卡');
insert into card values(5, '邮政卡');
insert into person values(1, '张三', 1);
insert into person values(2, '李四', 3);
insert into person values(3, '王五', 6);
select * from person inner join card on person.cardId=card.id; #inner join查询
select * from person join card on person.cardId=card.id; #join查询
select * from person left join card on person.cardId=card.id; #left join查询
select * from person left outer join card on person.cardId=card.id; #left outer join 查询
select * from person right join card on person.cardId = card.id; #right join查询
select * from person right outer join card on person.cardId =card.id; #right outer join查询
select * from person full join card on person.cardId=card.id; #全链接full join查询 MySQL不支持
select * from person left join card on person.cardId=card.id
union
select * from person right join card on person.cardId = card.id; #全链接
#### 事务
show databases;
create database bank;
use bank;
select @@autocommit; #自动提交,当我们去执行一个SQL语句的时候,效果会立即体现出来,且不能回滚
create table user(
id int primary key,
name varchar(20),
money float
);
insert into user values(1, 'a', 1000); #插入一条记录
insert into user values(2, 'b', 1000);
commit; #手动提交
# 事务回滚:撤销SQL语句执行效果
rollback;
set autocommit=0; #关闭MySQL自动提交(commit)
select @@autocommit;
insert into user values(2, 'b', 1000);
commit;
select * from user;
rollback;
SET SQL_SAFE_UPDATES = 0; #关闭安全模式
update user set money=money-100 where name='a';
update user set money=money+100 where name='b';
select * from user;
rollback;
-- 事务的特征---ACID
-- A 原子性,事务是最小的单位,不可以再分割;
-- C 一致性,事务要求同一个事务中的SQL语句,必须保证同时成功或者同时失败;
-- I 隔离性 事务1和事务2之间是具有隔离性;
-- D 持久性 事务一旦结束(commit, rollback)就不可返回。
-- 事务开启:
-- 1, 修改默认提交 set autocommit=0;
-- 2,begin;
-- 3,start transaction
-- 事务手动提交
-- commit;
-- 手动回滚
-- rollback
-- 事务的隔离性
-- 隔离级别 read -uncommitted > read -committed > repeatable-read > serializable;
-- 1. read uncommitted; 读未提交的
-- 如果事务a和事务b
-- a 事务对数据进行操作,在操作的过程中,事务没有被提交,但是b可以看见a操作的结果;
-- 如果两个不同的地方都在进行操作,如果事务a开启之后,他的数据可以被其他事务读取;
-- 这样就会出现脏读;
-- 脏读:一个事务读到另一个事务没有提交的数据,实际开发不容许脏读出现;
-- 2. read committed; 读已提交的
-- 虽然智能读取到另一个事务提交的数据,但还是会出现问题,就是
-- 读取同一个表的数据,发现前后不一致alter
-- 不可重复现象: read committed
select @@global.transaction_isolation; #查询隔离级别
set global transaction isolation level read committed; #修改隔离级别
start transaction ;
insert into user values(5, 'c', 100);
commit;
select * from user;
select avg(money) from user;
-- 3. repeatable read; 可以重复读
select @@global.transaction_isolation;
set global transaction isolation level repeatable read; #设置隔离级别为repeatable read
select * from user;
start transaction; #开启事务
insert into user values(6, 'd', 1000);
start transaction; #另一个事务开启
insert into user values(6, 'd', 1000);
-- 这种现象就叫做幻读
-- 事务a操作和事务b同时操作同一张表,事务a提交的数据也不能被事务b读到,就可以造成幻读;
-- 4.serializable; 串行化
-- 当user表被另外一个事务操作的时候,其他事务里面的写操作,是不可以进行的,
-- 直到进入排队状态(串行化),直到前一个事务结束之后,后面一个的写入操作才会执行
-- 在没有等待超市的情况下
-- 串行化带来的问题,性能特差,
set global transaction isolation level serializable; #修改隔离级别为串行化
select @@global.transaction_isolation; #查询隔离级别
start transaction; #开启事务
insert into user values(7, '赵铁柱', 1000);
select * from user;
start transaction; #另一个开启事务
insert into user values (8, '王小花', 1000);
use bank;
select * from user;
insert into user values(3, '小明', 1000);
insert into user values(4, '淘宝店', 1000);
select * from user;
select @@global.transaction_isolation; #查看数据库的隔离级别
set global transaction isolation level read uncommitted; #修改数据库隔离级别
start transaction;
update user set money=money-800 where name='小明';
update user set money=money+800 where name='淘宝店';
rollback;
select * from user;