//进入数据库管理
winpty mysql -u root -p
//查看所有的数据库
show databases;
//选中某个数据库
use ***
//退出数据库管理
exit、quit、\q
//创建一个名叫test的数据库
create database test;
//查看数据库中的所有数据表
show tables;
//创建pet数据表
create table pet(
name varchar(20),
owner varchar(20));
//查看pet数据表的结构
describe(desc) pet;
/*
增删改查
*/
//往pet数据表中添加数据
insert into pet
values('LuAng','zyf');
//查询pet表中的数据
select * from pet;
//删除testtype表中number=123的数据
delete from testtype where number = 123;
//删除所有行:
Delete From 表名称 或者 Truncate Table 表名称
//删除表:
Drop Table 表名称
//修改pet表中owner='zyf'的数据的name项为'XiaoAng'
update pet set name = 'XiaoAng' where owner = 'zyf';
//创建表后修改字段,往user表中添加一个age字段
alter table user add (age int);
DCL:授权
DDL:操作数据库,表
DQL:查询表中的数据
DML:增删改表中的数据
它能够唯一确定一张表中的一条记录,也就是我们通过给某个字段添加约束,就可以使得该字段不重复且不为空。
//id 后面 primary key 即id字段不重复且不为空
create table user(
id int primary key,
name varchar(20)
);
//创建表后添加主键约束,删除则将add改为drop后面不用选择字段
alter table user2 add (modify) primary key(id);
/*
复合主键
*/
create table user2(
id int,
name varchar(20),
password varchar(20),
//相当于 或 ,两个加起来不相等即可
primary key(id,name)
);
/*
自增约束auto_increment搭配主键约束可自动管理id字段
*/
create table user3(
id int primary key auto_increment,
name varchar(20)
);
//只插入name字段的值,id字段会自动生成 null或者0
insert into user3 values(null,'xiaoang');
约束修饰的字段的值不可以重复
//id字段不可以重复
create table user2(
id int unique,
name varchar(20)
);
//若是unique(id,name)则是id+name不重复即可
//删除唯一约束,删除id的唯一约束
alter table user2 drop index id;
约束修饰的字段的值不可以为空
//id字段不能为空
create table user2(
id int not null,
name varchar(20)
);
当我们插入字段值的时候,如果没有传值,就会使用默认值
//如果age没有传值,则为默认值18
create table user(
id int,
name varchar(20),
age int default 18
);
涉及到两个表:父表(主表),子表(副表)
//班级表,父表即主表
create table classes(
id int primary key,
name varchar(20)
);
//学生表,子表即副表
create table students(
id int primary key,
name varchar(20),
class_id int,
//外键约束指向classes表中的id字段
foreign key(class_id) references classes(id)
);
/*
主表classes中没有的数据值,在副表中是不可以使用的
主表中的纪录被附表引用是不可以被删除的
*/
数据表中的所有字段都是不可分割的原子值
字段值若是还可以继续拆分,就不满足第一范式
1NF+除主键外的每一列都要完全依赖于主键,
不完全依赖也就是出现了复合主键
若不是完全依赖于主键则要拆表
//订单表
//不满足第二范式,要拆分
create table myorder(
product_id int,
customer_id int,
product_name varchar(20),
customer_name varchar(20),
primary key(product_id,customer_id)
);
//拆成以下三个表
create table myorder(
order_id int primary key,
product_id int,
customer_id int
);
create table product(
id int primary key,
name varchar(20)
);
create table customer(
id int primary key,
name varchar(20)
);
2NF+除开主键列的其他列之间不能有传递依赖关系
create table myorder(
order_id int primary key,
product_id int,
customer_id int,
/*
×××不能这样,customer_phone可通过customer_id找到即依赖于customer_id
customer_phone varchar(15)
*/
);
//应写到下面
create table customer(
id int primary key,
name varchar(20)
phone varchar(15)
);
//创建学生表 学号,姓名,性别,生日,班级号
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) 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)
);
//创建成绩等级表
create table grade(
low int(3),
upp int(3),
grade char(1)
);
//添加学生信息
insert into student values('101','曾华','男','1977-09-07','95033');
insert into student values('102','匡明','男','1975-04-01','95033');
insert into student values('103','王丽','女','1979-06-02','95031');
insert into student values('104','李俊','女','1977-08-03','95033');
insert into student values('105','王芳','女','1973-01-04','95031');
insert into student values('106','陆军','男','1974-03-05','95033');
insert into student values('107','王璐','女','1978-09-06','95031');
insert into student values('108','张锋','男','1971-07-07','95033');
insert into student values('109','李森','男','1970-02-08','95031');
//添加教师信息
insert into teacher values('804','李成','男','1957-12-06','副教授','计算机系');
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('105','计算机导论','825');
insert into course values('245','操作系统','804');
insert into course values('166','数字电路','856');
insert into course values('888','高等数学','831');
//添加成绩信息
insert into score values('103','245','86');
insert into score values('105','245','75');
insert into score values('109','245','68');
insert into score values('103','105','92');
insert into score values('105','105','88');
insert into score values('109','105','76');
insert into score values('103','166','85');
insert into score values('105','166','79');
insert into score values('109','166','81');
insert into score values('101','166','82');
insert into score values('102','166','83');
//添加成绩等级
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');
student:
+-----+-------+------+---------------------+-------+
| sno | sname | ssex | sbirthday | class |
+-----+-------+------+---------------------+-------+
| 101 | 曾华 | 男 | 1977-09-07 00:00:00 | 95033 |
| 102 | 匡明 | 男 | 1975-04-01 00:00:00 | 95033 |
| 103 | 王丽 | 女 | 1979-06-02 00:00:00 | 95031 |
| 104 | 李俊 | 女 | 1977-08-03 00:00:00 | 95033 |
| 105 | 王芳 | 女 | 1973-01-04 00:00:00 | 95031 |
| 106 | 陆军 | 男 | 1974-03-05 00:00:00 | 95033 |
| 107 | 王璐 | 女 | 1978-09-06 00:00:00 | 95031 |
| 108 | 张锋 | 男 | 1971-07-07 00:00:00 | 95033 |
| 109 | 李森 | 男 | 1970-02-08 00:00:00 | 95031 |
+-----+-------+------+---------------------+-------+
teacher:
+-----+-------+------+---------------------+--------+------------+
| tno | tname | tsex | tbirthday | prof | depart |
+-----+-------+------+---------------------+--------+------------+
| 804 | 李成 | 男 | 1957-12-06 00:00:00 | 副教授 | 计算机系 |
| 825 | 王萍 | 女 | 1972-05-05 00:00:00 | 助教 | 计算机系 |
| 831 | 刘冰 | 女 | 1977-08-14 00:00:00 | 助教 | 电子工程系 |
| 856 | 张勋 | 男 | 1969-03-12 00:00:00 | 讲师 | 电子工程系 |
+-----+-------+------+---------------------+--------+------------+
course:
+-----+------------+-----+
| cno | cname | tno |
+-----+------------+-----+
| 105 | 计算机导论 | 825 |
| 166 | 数字电路 | 856 |
| 245 | 操作系统 | 804 |
| 888 | 高等数学 | 831 |
+-----+------------+-----+
score:
+-----+-----+--------+
| sno | cno | degree |
+-----+-----+--------+
| 101 | 166 | 82 |
| 102 | 166 | 83 |
| 103 | 105 | 92 |
| 103 | 166 | 85 |
| 103 | 245 | 86 |
| 105 | 105 | 88 |
| 105 | 166 | 79 |
| 105 | 245 | 75 |
| 109 | 105 | 76 |
| 109 | 166 | 81 |
| 109 | 245 | 68 |
+-----+-----+--------+
grade:
+------+------+-------+
| low | upp | grade |
+------+------+-------+
| 90 | 100 | A |
| 80 | 89 | B |
| 70 | 79 | C |
| 60 | 69 | D |
| 0 | 59 | E |
+------+------+-------+
distinct 不重复
表示或者关系的查询 in
or 表示或者
order by...desc 以...降序 asc 升序
count(*) 统计个数
max(degree) degree的最大值
avg(degree) 平均数
group by 分组
having筛选分组之后的数据
where筛选分组之前的数据
like '1%' 模糊查询 像以1开头的的数据
not like 模糊查询取反
student.sno=score.sno = 相当于对两个表自然连接
year(日期) 可获得日期中的年份
now() 获取当前系统时间
union 求并集 not in 不在其中
any 至少一个 所有
as 重命名
max() min() 获取当前列的最大值最小值
/*
查询练习
*/
//1.查询student表的所有记录
select * from student;
//2.查询student表中的所有记录的sname、ssex和class列
select sname,ssex,class from student;
//3.查询教师所有的单位即不重复的depart列 /*distinct 不重复*/
select distinct depart from teacher;
//4.查询score表中成绩在60到80之间的所有记录 /*1.查询区间,2.使用运算符*/
select * from score where degree between 60 and 80;
select * from score where degree > 60 and degree < 80;
//5.查询score表中成绩为85,86或88的记录 /*表示或者关系的查询 in*/
select * from score where degree in(85,86,88);
//6.查询student表中‘95031’班或性别为‘女’的同学记录 /*or 表示或者*/
select * from student where class = '95031' or ssex = '女';
//7.以sno降序查询student表中的所有记录 /*order by...desc 以...降序*/
select * from student order by sno desc;
//8.以cno升序、degree降序查询score表的所有记录 /*asc 升序*/
select * from score order by cno asc,degree desc;
//9.查询‘95031’班的学生人数 /*count(*) 统计个数*/
select count(*) from student where class = '95031';
//10.查询score表中的最高分的学生学号和课程号(子查询或者排序)
/*max(degree) degree的最大值 select返回的是记录,从中再查询*/
select sno,cno from score where degree=(select max(degree) from score);
//11.查询每门课的平均成绩 /*avg(degree) 平均数*/
select avg(degree) from score where cno = '245';
/*group by 分组*/
select cno,avg(degree) from score group by cno;
//12.查询score表中至少有两名学生选修的并以1开头的课程号
/*分组后用having筛选 count(*)是个数 like '1%' 像以1开头的的数据
where筛选分组之前的数据,having筛选分组之后的*/
select cno from score group by cno
having count(*)>=2 and cno like '1%';
//13.查询分数大于70,小于90的sno列
select sno,degree from score where degree>70 and degree<90;
//14.查询所有学生的sname,cno和degree列
/*多表查询 条件是student.sno=score.sno = 相当于对两个表自然连接 */
select sname,cno,degree from student,score where student.sno = score.sno;
//15.查询所有学生的sno,cname和degree列
select sno,cname,degree from course,score where course.cno=score.cno;
//16.查询所有学生的sname,cname和degree列 /*三表关联查询*/
select sname,cname,degree from student,course,score where student.sno=score.sno and course.cno=score.cno;
//17.查询‘95031’班学生的每门课的平均分
/*
子查询:查询95031班的sno
select sno from student where class='95031';
分组:查询每个课程的分数
select cno from score where... group by cno;
子查询加分组
*/
select cno,avg(degree)
from score
where sno in (select sno from student where class='95031')
group by cno;
//18.查询选修‘105’课程的成绩高于‘109’号同学‘105’课程成绩的所有同学的记录
/* 子查询
查询所cno=105且成绩大于某个数的所有记录
select * from score where cno = '105' and degree>...;
查询109号同学的105号课程的成绩
select degree from score where sno = '109' and cno = '105';
*/
select * from score where cno = '105' and degree>(select degree from score where sno = '109' and cno = '105');
//19.查询成绩高于学号为‘109’,课程号为‘105’的成绩的所有记录
select degree from score where degree>(select degree from score where sno = '109' and cno = '105');
//20.查询和学号为108,101的同学同年出生的所有同学的sno,sname,sbirthday列
/*year(日期) 可获得日期中的年份*/
select sno,sname,sbirthday from student where year(sbirthday) in (select year(sbirthday) from student where sno in(108,101));
//21.查询‘李成’教师任课的学生成绩
/* 多层嵌套子查询
1.select tno from teacher where tname = '李成';
2.select cno from course where tno = (...);
3.select * from score where cno = (...);
*/
select * from score where cno = (select cno from course where tno = (select tno from teacher where tname = '李成'));
//22.查询选修某课程的同学人数不少于5人的教师姓名
/*
select cno from score group by cno having count(*)>=5;
select tno from course where cno=(...)
select tname from teacher where tno=(...)
*/
select tname from teacher where tno=(select tno from course where cno=(select cno from score group by cno having count(*)>=5));
//23.查询存在有85分以上成绩的课程cno
select distinct cno from score where degree > 85;
//24.查询出‘计算机系’教师所教的课程的成绩表
/*
select tno from teacher where depart = '计算机系';
select cno from course where tno in (...);
select * from score where cno in (...);
*/
select * from score where cno in (select cno from course where tno in (select tno from teacher where depart = '计算机系'));
//25.查询‘计算机系’与‘电子工程系’不同职称的教师的tname和prof
/* union 求并集 not in 不在其中*/
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 = '计算机系');
//26.查询105课程的成绩大于至少一个245课程的成绩的cno,sno,degree,并按degree从高到低排序
/* any 至少一个 all 所有 */
select * from score
where cno = '105'
and degree > any(select degree from score where cno = '245')
order by degree desc;
//27.查询所有教师和同学的name,sex,birthday
/* as 重命名 */
select tname as name,tsex as sex,tbirthday as birthday from teacher
union
select sname,ssex,sbirthday from student;
//28.查询成绩比该课程平均成绩低的同学的成绩表
/*复制表数据做条件查询*/
select * from score a where degree<(select avg(degree) from score b where a.cno=b.cno);
//29.查询至少有两名男生的班号
/*分组加条件筛选*/
select class from student where ssex='男' group by class having count(*) >= 2;
//30.查询student表中不姓‘王’的同学记录
/*not like 模糊查询取反*/
select * from student where sname not like '王%';
//31.查询student表中每个学生的姓名和年龄
/*year() 获取年份 now() 获取当前系统时间 不存在的列 要有as*/
select sname,year(now())-year(sbirthday) as '年龄' from student;
//32.查询student表中最大和最小的sbirthday日期值
/*max() min() 获取当前列的最大值最小值*/
select max(sbirthday) as '最大',min(sbirthday) as '最小' from student;
33.查询所有同学的sno,cno,grade列,并按ABCDE顺序排列
/*按等级查询*/
select sno,cno,grade from score,grade where degree between low and upp order by grade;
//创建person表
create table person(
id int,
name varchar(20),
cardId int
);
//创建card表
create table card(
id int,
name varchar(20)
);
//添加数据
insert into person values(1,'张三',1);
insert into person values(2,'李四',3);
insert into person values(3,'王五',6);
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,'邮政卡');
//数据表
person:
+------+------+--------+
| id | name | cardId |
+------+------+--------+
| 1 | 张三 | 1 |
| 2 | 李四 | 3 |
| 3 | 王五 | 6 |
+------+------+--------+
card:
+------+--------+
| id | name |
+------+--------+
| 1 | 饭卡 |
| 2 | 建行卡 |
| 3 | 农行卡 |
| 4 | 工商卡 |
| 5 | 邮政卡 |
+------+--------+
join 或者inner join
内联查询:就是两张表的数据,通过某个人字段相对,查询出相关记录数据
select * from person join card on person.cardId=card.id;
left join 或者 left outer join
左外连接:会把左边表里面的所有数据取出来,而右边表中的数据,如果有相等的就显示出来,如果没有就会补NULL==
select * from person left join card on person.cardId=card.id;
right join 或者 right outer join
右外连接:会把右边表里面的所有数据取出来,而左边表中的数据,如果有相等的就显示出来,如果没有就会补NULL
select * from person right join card on person.cardId=card.id;
full join 或者 full outer 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;
mysql是默认开启事务自动提交的
事务给我们提供了一个返回的机会
/*autocommit为1则为自动提交*/
select @@autocommit;
/*rollback 事务回滚,即撤销上一步操作 而自动提交是不允许事务回滚的*/
rollback;
/*设置自动提交为false 即autocommit为0*/
set autocommit = 0;
/*不是自动提交的情况下 commit手动提交 提交后则不能事务回滚*/
commit;
/*在autocommit为1的情况下 可手动开启一个不自动提交的事务 可进行事务回滚 */
/*在执行语句前*/
begin; /*或者*/ start transaction;
/*commit前都可rollback*/
a事务对数据进行操作,在操作的过程中事务没有被提交,但是b可以看见a操作的结果
/*查看数据库的隔离级别*/
<系统级别的>
select @@global.transaction_isolation;
<会话级别的>
select @@transaction_isolation;
/*修改隔离级别*/
set global transaction isolation level read uncommitted;
/*脏读:一个事务读到了另外一个事务没有提交的数据,就叫脏读, 实际开发不允许脏读*/
可能出现问题:读取同一个表的数据,发现前后不一致
可能出现幻读:事务a和事务b (都开启事务了) 同时操作一张表,事务a提交的数据,也不能被事务b读到
可能出现串行化:当user表被事务a操作时,其他事务里面的写操作是不可以进行的,已经开始的也会进入排队状态(串行化),直到事务a执行commit操作,其他事务的写操作才可以执行(在没有等待超时的情况下)
-- 使用mysql数据库
use mysql;
-- 查询用户表
select * from user;
-- 创建用户 localhost 代表本机 % 代表所有主机
create user 'kilig'@'%' identified by 'qepwq';
-- 删除用户
drop user 'kilig'@'%';
-- 修改密码
update user set password = password('新密码') where user = 'kilig';
-- 查询权限
show grants for 'kilig'@'%';
-- 授予权限 all 所有权限 *.* 所有数据库的所有权限
grant all on *.* to 'kilig'@'%';
-- 撤销权限
revoke all on *.* from ''@'';